home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / cmds / oldwish / RCS / wishCmd.c,v < prev    next >
Encoding:
Text File  |  1989-07-13  |  68.5 KB  |  2,808 lines

  1. head     1.5;
  2. branch   ;
  3. access   ;
  4. symbols  ;
  5. locks    mgbaker:1.5; strict;
  6. comment  @ * @;
  7.  
  8.  
  9. 1.5
  10. date     89.01.19.16.51.50;  author mgbaker;  state Exp;
  11. branches ;
  12. next     1.4;
  13.  
  14. 1.4
  15. date     89.01.11.11.30.30;  author mlgray;  state Exp;
  16. branches ;
  17. next     1.3;
  18.  
  19. 1.3
  20. date     88.11.03.19.44.00;  author mlgray;  state Exp;
  21. branches ;
  22. next     1.2;
  23.  
  24. 1.2
  25. date     88.11.02.14.49.18;  author mlgray;  state Exp;
  26. branches ;
  27. next     1.1;
  28.  
  29. 1.1
  30. date     88.10.03.12.45.42;  author mlgray;  state Exp;
  31. branches ;
  32. next     ;
  33.  
  34.  
  35. desc
  36. @X11: works pretty much now.
  37. @
  38.  
  39.  
  40. 1.5
  41. log
  42. @Fixed printing string in WishPrintTclError.  I still don't understand
  43. why I must copy it to a buffer first.
  44. @
  45. text
  46. @/* 
  47.  * wishCmd.c --
  48.  *
  49.  *    Commands for wish.
  50.  *
  51.  * Copyright 1987 Regents of the University of California
  52.  * All rights reserved.
  53.  * Permission to use, copy, modify, and distribute this
  54.  * software and its documentation for any purpose and without
  55.  * fee is hereby granted, provided that the above copyright
  56.  * notice appear in all copies.  The University of California
  57.  * makes no representations about the suitability of this
  58.  * software for any purpose.  It is provided "as is" without
  59.  * express or implied warranty.
  60.  */
  61.  
  62. #ifndef lint
  63. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishCmd.c,v 1.4 89/01/11 11:30:30 mlgray Exp Locker: mgbaker $ SPRITE (Berkeley)";
  64. #endif not lint
  65.  
  66. #include <sys/types.h>
  67. #include <sys/stat.h>
  68. #include "sx.h"
  69. #include "util.h"
  70. typedef    int    Boolean;
  71. #define    FALSE    0
  72. #define    TRUE    1
  73. #include "monitorClient.h"
  74. #include "wishInt.h"
  75.  
  76. /*
  77.  * Range of chars for which the standard insert binding is to be used,
  78.  * unless overridden by something else.
  79.  */
  80. static    char    insertFirst = 040;
  81. static    char    insertLast = 0176;
  82.  
  83.  
  84.  
  85. /*
  86.  *----------------------------------------------------------------------
  87.  *
  88.  * WishBindCmd --
  89.  *
  90.  *    Create (or replace or delete) a keystroke binding.  I should change
  91.  *    this to match mx so that a missing command argument means to return
  92.  *    the enumeration of the bindings with the prefix, rather than to
  93.  *    delete the binding.
  94.  *
  95.  * Syntax:
  96.  *    bind sequence [command]
  97.  *
  98.  * Results:
  99.  *    Returns TCL results.
  100.  *
  101.  * Side effects:
  102.  *    A new keystroke binding gets added to or deleted from the
  103.  *    window's command table.
  104.  *
  105.  *----------------------------------------------------------------------
  106.  */
  107. int
  108. WishBindCmd(aWindow, interp, argc, argv)
  109.     WishWindow    *aWindow;
  110.     Tcl_Interp        *interp;
  111.     int            argc;
  112.     char        **argv;
  113. {
  114.     if ((argc != 3) && (argc != 2)) {
  115.     sprintf(interp->result, "%s should be \"%.50s [sequence [command]]\"",
  116.         "wrong number of args:", argv[0]);
  117.     return TCL_ERROR;
  118.     }
  119.     if (argc == 3) {
  120.     Cmd_BindingCreate(aWindow->cmdTable, argv[1], argv[2]);
  121.     } else {
  122.     Cmd_BindingDelete(aWindow->cmdTable, argv[1]);
  123.     }
  124.     return TCL_OK;
  125. }
  126.  
  127.  
  128. /*
  129.  *----------------------------------------------------------------------
  130.  *
  131.  * WishChangeDirCmd --
  132.  *
  133.  *    Change the directory of the display.  Force associated shell
  134.  *    window(s) to update current directory also.
  135.  *
  136.  * Syntax:
  137.  *    changeDirectory dirName
  138.  *
  139.  * Results:
  140.  *    Returns TCL_OK if all went well, or various TCL errors if not.
  141.  *
  142.  * Side effects:
  143.  *    Current directory changes.
  144.  *
  145.  *----------------------------------------------------------------------
  146.  */
  147. int
  148. WishChangeDirCmd(aWindow, interp, argc, argv)
  149.     WishWindow    *aWindow;
  150.     Tcl_Interp        *interp;
  151.     int            argc;
  152.     char        **argv;
  153. {
  154.     struct    stat    dirAtts;
  155.     char        *newDir;
  156.  
  157.     if (argc != 2) {
  158.     sprintf(interp->result, "%s \"%.50s dirName\"",
  159.         "wrong # args: should be", argv[0]);
  160.     return TCL_ERROR;
  161.     }
  162.     if ((newDir = Util_CanonicalDir(argv[1], aWindow->dir, (char *) NULL))
  163.         == NULL) {
  164.     sprintf(interp->result,
  165.         "Couldn't figure out directory name %s.", argv[1]);
  166.     return TCL_ERROR;
  167.     }
  168.     /* Check the validity of the new dir. */
  169.     if (lstat(newDir, &dirAtts) != 0) {
  170.     sprintf(interp->result,
  171.         "Cannot switch to dir %s.  Maybe it doesn't exist?", newDir);
  172.     free(newDir);
  173.     return TCL_ERROR;    /* should above message be passed to routine? */
  174.     }
  175.     if ((dirAtts.st_mode & S_IFMT) != S_IFDIR) {    /* not a directory */
  176.     sprintf(interp->result, "%s is not a directory.", newDir);
  177.     free(newDir);
  178.     return TCL_ERROR;    /* should above message be passed to routine? */
  179.     }
  180.     WishChangeDir(aWindow, newDir);    /* does everything */
  181.     free(newDir);
  182.  
  183.     return TCL_OK;
  184. }
  185.  
  186.  
  187. /*
  188.  *----------------------------------------------------------------------
  189.  *
  190.  * WishChangeFieldsCmd --
  191.  *
  192.  *    Change the fields displayed with each file.
  193.  *
  194.  * Syntax:
  195.  *    changeFields [fields]
  196.  *
  197.  * Results:
  198.  *    Returns TCL_OK if all went well, or TCL errors if not.
  199.  *
  200.  * Side effects:
  201.  *    The fields displayed for each file will change.  The user will be
  202.  *    prompted to see if he wishes to make the new sorting method the
  203.  *    default method for the directory.
  204.  *
  205.  *----------------------------------------------------------------------
  206.  */
  207. int
  208. WishChangeFieldsCmd(aWindow, interp, argc, argv)
  209.     WishWindow    *aWindow;
  210.     Tcl_Interp        *interp;
  211.     int            argc;
  212.     char        **argv;
  213. {
  214.     int    which;
  215.     int    length;
  216.     int    arg;
  217.     int    didEnter = 0;
  218.     int    didExpose = 0;
  219.     int    didMouse = 0;
  220.  
  221.     /*
  222.      * any number of args may be okay here, depending on how many fields they
  223.      * wish to display.
  224.      */
  225.     aWindow->displayInstructions = 0;
  226.     if (argc > 1) {
  227.     for (arg = 1; arg < argc; arg++) {
  228.         length = strlen(argv[arg]);
  229.         if (strncmp(argv[arg], "name", length) == 0 ||
  230.             strncmp(argv[arg], "Name", length) == 0) { /* default */
  231.         continue;
  232.         }
  233.         /*
  234.          * atime = access time = time file data last read or modified.
  235.          * ctime = desc modify time = time file status last changed, by
  236.          *        writing or inode changes.
  237.          * mtime = data modify time = time data last modified.
  238.          */
  239.  
  240.         if (strncmp(argv[arg], "size", length) == 0 ||
  241.             strncmp(argv[arg], "Size", length) == 0) {
  242.         aWindow->displayInstructions |= WISH_SIZE_FIELD;
  243.         continue;
  244.         }
  245.         if (strncmp(argv[arg], "atime", length) == 0 ||
  246.             strncmp(argv[arg], "Atime", length) == 0 ||
  247.             strncmp(argv[arg], "accesstime", length) == 0 ||
  248.             strncmp(argv[arg], "accessTime", length) == 0 ||
  249.             strncmp(argv[arg], "AccessTime", length) == 0) {
  250.         aWindow->displayInstructions |= WISH_ATIME_FIELD;
  251.         continue;
  252.         }
  253.         if (strncmp(argv[arg], "ctime", length) == 0 ||
  254.             strncmp(argv[arg], "Ctime", length) == 0 ||
  255.             strncmp(argv[arg], "descmodtime", length) == 0 ||
  256.             strncmp(argv[arg], "descModTime", length) == 0 ||
  257.             strncmp(argv[arg], "DescModTime", length) == 0 ||
  258.             strncmp(argv[arg], "descmodifytime", length) == 0 ||
  259.             strncmp(argv[arg], "descModifyTime", length) == 0 ||
  260.             strncmp(argv[arg], "DescModifyTime", length) == 0 ||
  261.             strncmp(argv[arg], "descriptormodifytime", length) == 0 ||
  262.             strncmp(argv[arg], "descriptorModifyTime", length) == 0 ||
  263.             strncmp(argv[arg], "DescriptorModifyTime", length) == 0) {
  264.         aWindow->displayInstructions |= WISH_DTIME_FIELD;
  265.         continue;
  266.         }
  267.         if (strncmp(argv[arg], "mtime", length) == 0 ||
  268.             strncmp(argv[arg], "Mtime", length) == 0 ||
  269.             strncmp(argv[arg], "datamodtime", length) == 0 ||
  270.             strncmp(argv[arg], "dataModTime", length) == 0 ||
  271.             strncmp(argv[arg], "DataModTime", length) == 0 ||
  272.             strncmp(argv[arg], "datamodifytime", length) == 0 ||
  273.             strncmp(argv[arg], "dataModifyTime", length) == 0 ||
  274.             strncmp(argv[arg], "DataModifyTime", length) == 0) {
  275.         aWindow->displayInstructions |= WISH_MTIME_FIELD;
  276.         continue;
  277.         }
  278.         sprintf(interp->result, "%s %s %s", "bad argument, the possible",
  279.             "arguments are size, atime (AccessTime),",
  280.             "mtime (DataModifyTime), and dtime (DescriptorModifyTime)");
  281.         return TCL_ERROR;
  282.     }
  283.     goto finishedFields;
  284.     }
  285.  
  286.     /* Protect data structure from redraws initiated in Sx_Notify */
  287.     aWindow->notifierP = TRUE;
  288.     which = Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  289.         "Display Size?", NULL, TRUE, "Yes", "No", "Stop",
  290.         (char *) NULL);
  291.     if (which == 0) {
  292.     aWindow->displayInstructions |= WISH_SIZE_FIELD;
  293.     } else if (which == 2) {
  294.     goto finishedFields;
  295.     }
  296.     which = Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  297.         "Display AccessTime?", NULL, TRUE, "Yes", "No", "Stop",
  298.         (char *) NULL);
  299.     if (which == 0) {
  300.     aWindow->displayInstructions |= WISH_ATIME_FIELD;
  301.     } else if (which == 2) {
  302.     goto finishedFields;
  303.     }
  304.     which = Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  305.         "Display DataModifyTime?", NULL, TRUE, "Yes", "No", "Stop",
  306.         (char *) NULL);
  307.     if (which == 0) {
  308.     aWindow->displayInstructions |= WISH_MTIME_FIELD;
  309.     } else if (which == 2) {
  310.     goto finishedFields;
  311.     }
  312.     which = Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  313.         "Display DescriptorModifyTime?", NULL, TRUE, "Yes", "No",
  314.         "Stop", (char *) NULL);
  315.     if (which == 0) {
  316.     aWindow->displayInstructions |= WISH_DTIME_FIELD;
  317.     } else if (which == 2) {
  318.     goto finishedFields;
  319.     }
  320. finishedFields:
  321.     ;    /* nothing */
  322.  
  323.     /* Safe now. */
  324.     aWindow->notifierP = FALSE;
  325.  
  326.     if (aWindow->dontDisplayChangesP == FALSE) {
  327.     /* update display */
  328.     if (aWindow->firstElement == UNINITIALIZED) {
  329.         aWindow->firstElement = 1;
  330.     }
  331.     WishSetPositions(aWindow);
  332.     }
  333.  
  334.     return TCL_OK;
  335. }
  336.  
  337. #ifdef NOTDEF
  338.  
  339. /*
  340.  *----------------------------------------------------------------------
  341.  *
  342.  * WishChangeGroupsCmd --
  343.  *
  344.  *    Change the definition of a group.
  345.  *
  346.  * Syntax:
  347.  *    changeGroups
  348.  *
  349.  * Results:
  350.  *    Returns TCL_OK if all went well, or TCL errors if not.
  351.  *    error occurred.
  352.  *
  353.  * Side effects:
  354.  *    The pattern matching rules or associated command bindings for the
  355.  *    group may change.
  356.  *
  357.  *----------------------------------------------------------------------
  358.  */
  359. int
  360. WishChangeGroupsCmd(aWindow, interp, argc, argv)
  361.     WishWindow    *aWindow;
  362.     Tcl_Interp        *interp;
  363.     int            argc;
  364.     char        **argv;
  365. {
  366.     static    int    count = 0;
  367.     FILE    *stream;
  368.     int    pid;
  369.     char    buffer[MAXPATHLEN];
  370.     char    **args;
  371.     int    pidArray[1];
  372.     WishGroup    *grpPtr;
  373.     int    childPid;
  374.  
  375.     if (strcmp(argv[0], "deleteGroup") == 0 ||
  376.         strcmp(argv[0], "deletegroup") == 0) {
  377.     /* delete the group and clean up */
  378.     }
  379.     if (
  380.     /*
  381.      * open a file
  382.      */
  383.     Proc_GetIDs(&pid, NULL, NULL, NULL, NULL);
  384.     sprintf(buffer, "%s%d.%d", "/tmp/tmpWish", pid, count);
  385.     count++;
  386.     if ((stream = fopen(buffer, "w")) == NULL) {
  387.     sprintf(interp->result, "%s %s %s",
  388.         "Couldn't open file", buffer,
  389.         "in which to let you edit the selection rules.");
  390.     return TCL_ERROR;
  391.     }
  392.     for (grpPtr = aWindow->groupList; grpPtr != NULL;
  393.         grpPtr = grpPtr->nextPtr) {
  394.     fputs("Select:\n", stream);
  395.     fputs(grpPtr->rule, stream);
  396.     fputs("\n", stream);
  397.     if (grpPtr->name != NULL) {
  398.         fputs("GroupName:\n", stream);
  399.         fputs(grpPtr->name, stream);
  400.         fputs("\n\n", stream);
  401.     }
  402.     }
  403.     fclose(stream);
  404.     /* I should be checking ferror for above PutStrings and Close return. */
  405.     /* close file and mx it. */
  406.     /* parse file when mx returns. */
  407.     if (Proc_Fork(TRUE, &childPid) == PROC_CHILD_PROC) {
  408.     /*child*/
  409.     /* what to do about this pathname? */
  410.     args = (char **) malloc(4 * sizeof (char *));
  411.     args[0] = Util_Strcpy(NULL, "mx");
  412.     args[1] = Util_Strcpy(NULL, "-D");
  413.     args[2] = Util_Strcpy(NULL, buffer);    /* CORE LEAK */
  414.     args[3] = NULL;
  415.     Proc_Exec("/sprite2/users/ouster/mx10/mx", args, FALSE);
  416.     /* error if returned. */
  417.     sprintf(wishErrorMsg, "Exec of %s returned.",
  418.         "/sprite2/users/ouster/mx10/mx");
  419.     aWindow->notifierP = TRUE;
  420.     Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  421.         wishErrorMsg, NULL, TRUE, "Skip command", (char *) NULL);
  422.     aWindow->notifierP = FALSE;
  423.     exit(-1);
  424.     } else {
  425.     /*parent waits */
  426.     pidArray[0] = childPid;
  427.     Proc_Wait(1, pidArray, PROC_WAIT_BLOCK, NULL, NULL, NULL, NULL, NULL);
  428.     }
  429.     if ((stream = fopen(buffer, "a")) == NULL) {
  430.     sprintf(wishErrorMsg, "%s %s %s",
  431.         "Couldn't open file", buffer,
  432.         "in which you edited the selection rules.");
  433.     aWindow->notifierP = TRUE;
  434.     Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  435.         wishErrorMsg, NULL, TRUE, "Skip command", (char *) NULL);
  436.     aWindow->notifierP = FALSE;
  437.     return TCL_ERROR;
  438.     }
  439.     if (aWindow->sortingInstructions & WISH_ALPHA_SORT) {
  440.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  441.         fputs("Sort:\nAlphaReverse\n\n", stream);
  442.     } else {
  443.         fputs("Sort:\nAlpha\n\n", stream);
  444.     }
  445.     }
  446.     if (aWindow->sortingInstructions & WISH_ATIME_SORT) {
  447.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  448.         fputs("Sort:\nAccessTimeReverse\n\n", stream);
  449.     } else {
  450.         fputs("Sort:\nAccessTime\n\n", stream);
  451.     }
  452.     }
  453.     if (aWindow->sortingInstructions & WISH_MTIME_SORT) {
  454.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  455.         fputs("Sort:\nDataModifyTimeReverse\n\n", stream);
  456.     } else {
  457.         fputs("Sort:\nDataModifyTime\n\n", stream);
  458.     }
  459.     }
  460.     if (aWindow->sortingInstructions & WISH_DTIME_SORT) {
  461.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  462.         fputs("Sort:\nDescriptorModifyTimeReverse\n\n", stream);
  463.     } else {
  464.         fputs("Sort:\nDescriptorModifyTime\n\n", stream);
  465.     }
  466.     }
  467.     if (aWindow->sortingInstructions & WISH_SIZE_SORT) {
  468.     if (aWindow->sortingInstructions & WISH_REVERSE_SORT) {
  469.         fputs("Sort:\nSizeReverse\n\n", stream);
  470.     } else {
  471.         fputs("Sort:\nSize\n\n", stream);
  472.     }
  473.     }
  474.     if (aWindow->displayInstructions & WISH_NAME_FIELD) {
  475.     fputs("Display:\nName\n\n", stream);
  476.     }
  477.     if (aWindow->displayInstructions & WISH_ATIME_FIELD) {
  478.     fputs("Display:\nAccessTime\n\n", stream);
  479.     }
  480.     if (aWindow->displayInstructions & WISH_MTIME_FIELD) {
  481.     fputs("Display:\nDataModifyTime\n\n", stream);
  482.     }
  483.     if (aWindow->displayInstructions & WISH_DTIME_FIELD) {
  484.     fputs("Display:\nDescriptorModifyTime\n\n", stream);
  485.     }
  486.     if (aWindow->displayInstructions & WISH_SIZE_FIELD) {
  487.     fputs("Display:\nSize\n\n", stream);
  488.     }
  489.     fclose(stream);
  490.  
  491.     WishGarbageCollect(aWindow);
  492. #ifdef FUTURE
  493.     /*
  494.      * This routine was changed not to take second arg!
  495.      */
  496.     if (WishGatherNames(aWindow, buffer) != TCL_OK) {
  497.     return bad value and switch directories?
  498.     error string will be displayed in top-level display thingy?
  499.     }
  500. #endif FUTURE
  501.     
  502.     /* should it repick the size here if aWindow->pickSizeP is true? */
  503.     aWindow->firstElement = 1;
  504.     WishSetPositions(aWindow);
  505.     /* WishRedraw will be called from event caused in WishSetPositions() */
  506.  
  507.     /* ask if they want to make it permanent. */
  508.  
  509.     return TCL_OK;
  510. }
  511. #endif NOTDEF
  512.  
  513.  
  514.  
  515. /*
  516.  *----------------------------------------------------------------------
  517.  *
  518.  * WishChangeGroupCmd --
  519.  *
  520.  *    Change the definition of a group.
  521.  *
  522.  * Syntax:
  523.  *    changeGroup name newDefType newDef
  524.  *
  525.  * Results:
  526.  *    Returns TCL_OK if all went well, or TCL errors if not.
  527.  *
  528.  * Side effects:
  529.  *    The specified group will be changed.
  530.  *
  531.  *----------------------------------------------------------------------
  532.  */
  533. int
  534. WishChangeGroupCmd(aWindow, interp, argc, argv)
  535.     WishWindow    *aWindow;
  536.     Tcl_Interp        *interp;
  537.     int            argc;
  538.     char        **argv;
  539. {
  540.     WishGroup    *grpPtr;
  541.     WishGroup    *newGrpPtr;
  542.     WishGroup    *bPtr;
  543.  
  544.     if (argc != 4) {
  545.     sprintf(interp->result, "%s %s", "Wrong # of args. Must be 4 args,",
  546.         "\"changeGroup name newDefType newDef\"");
  547.     return TCL_ERROR;
  548.     }
  549.  
  550.     /* Make sure no other group already has the new definition. */
  551.     for (grpPtr = aWindow->groupList; grpPtr != NULL;
  552.         grpPtr = grpPtr->nextPtr) {
  553.     if (strcmp(argv[3], grpPtr->rule) == 0) {
  554.         if (grpPtr->fileList == NULL && aWindow->hideEmptyGroupsP) {
  555.             sprintf(interp->result, "%s %s, %s",
  556.             "A group already has the definition", argv[3],
  557.             "but it may not be visible since no files match it.");
  558.         } else {
  559.         sprintf(interp->result, "A group already has the definition %s",
  560.             argv[3]);
  561.         }
  562.         return TCL_ERROR;
  563.     }
  564.     }
  565.  
  566.     /* find group to replace */
  567.     if (aWindow->groupList == NULL) {
  568.     sprintf(interp->result,
  569.         "No groups have been defined in order to change one");
  570.     return TCL_ERROR;
  571.     }
  572.  
  573.     bPtr = NULL;
  574.     for (grpPtr = aWindow->groupList; grpPtr != NULL;
  575.         grpPtr = grpPtr->nextPtr) {
  576.     if (strcmp(argv[1], grpPtr->rule) == 0) {
  577.         break;
  578.     }
  579.     bPtr = grpPtr;
  580.     }
  581.  
  582.     if (grpPtr == NULL) {
  583.     sprintf(interp->result, "No group with that definition");
  584.     return TCL_ERROR;
  585.     }
  586.  
  587.  
  588.     newGrpPtr = (WishGroup *) malloc(sizeof (WishGroup));
  589.  
  590.     /* test the new group's definition */
  591.     if (GetNewGroup(aWindow, interp, argv + 2, newGrpPtr) != TCL_OK) {
  592.     free(newGrpPtr);
  593.     return TCL_ERROR;
  594.     }
  595.  
  596.     newGrpPtr->nextPtr = grpPtr->nextPtr;
  597.  
  598.     WishGarbageGroup(aWindow, grpPtr);
  599.  
  600.     if (bPtr == NULL) {
  601.     aWindow->groupList = newGrpPtr;
  602.     } else {
  603.     bPtr->nextPtr = newGrpPtr;
  604.     }
  605.     if (aWindow->dontDisplayChangesP == FALSE) {
  606.     /* update display */
  607.     if (aWindow->firstElement == UNINITIALIZED) {
  608.         aWindow->firstElement = 1;
  609.     }
  610.     WishSetPositions(aWindow);
  611.     }
  612.     
  613.     return TCL_OK;
  614. }
  615.  
  616.  
  617. /*
  618.  *----------------------------------------------------------------------
  619.  *
  620.  * GetNewGroup --
  621.  *
  622.  *    Initialize and collect files for a new group.
  623.  *
  624.  * Results:
  625.  *    Returns TCL_OK if all went well, or TCL errors if not.
  626.  *
  627.  * Side effects:
  628.  *    Memory will be allocated for various things.
  629.  *
  630.  *----------------------------------------------------------------------
  631.  */
  632. int
  633. GetNewGroup(aWindow, interp, argv, newGrpPtr)
  634.     WishWindow    *aWindow;
  635.     Tcl_Interp        *interp;
  636.     char        **argv;
  637.     WishGroup        *newGrpPtr;
  638. {
  639.     int        procArgc;
  640.     char    **procArgv;
  641.     int        num;
  642.  
  643.     /* parse command arguments */
  644.     if (strcmp("comparison", argv[0]) == 0) {    /* simple comp stuff */
  645.     newGrpPtr->defType = COMPARISON;
  646.     newGrpPtr->rule = Util_Strcpy((char *) NULL, argv[1]);
  647.     /* test new grp def */
  648.     if (Pattern_Match(newGrpPtr->rule, "x") < 0) {
  649.         sprintf(interp->result,
  650.             "The comparison rule {%s} contains an error",
  651.             newGrpPtr->rule);
  652.         free(newGrpPtr->rule);
  653.         return TCL_ERROR;
  654.     }
  655.     } else if (strcmp("proc", argv[0]) != 0) {    /* bad def */
  656.     sprintf(interp->result, "Bad group definition type %s", argv[0]);
  657.     return TCL_ERROR;
  658.     } else {        /* TCL proc */
  659.     newGrpPtr->defType = PROC;
  660.     /* get name of proc */
  661.     if (Tcl_SplitList(interp, argv[1], &procArgc, &procArgv) != TCL_OK) {
  662.         return TCL_ERROR;
  663.     }
  664.     newGrpPtr->rule = Util_Strcpy((char *) NULL, procArgv[1]);
  665.     if (Tcl_Eval(interp, argv[1], '\0', NULL) != TCL_OK) {
  666.         free(newGrpPtr->rule);
  667.         free(procArgv);
  668.         return TCL_ERROR;
  669.     }
  670.     /* Will this really free it?  Tcl man page says so... */
  671.     free(procArgv);
  672.  
  673.     /* test new grp def */
  674.     if (WishDoTclSelect(interp, newGrpPtr->rule, "x", &num) != TCL_OK) {
  675.         free(newGrpPtr->rule);
  676.         return TCL_ERROR;
  677.     }
  678.     }
  679.     newGrpPtr->nextPtr = NULL;
  680.     newGrpPtr->myColumn = UNINITIALIZED;
  681.     newGrpPtr->headerWindow = UNINITIALIZED;
  682.     newGrpPtr->x = UNINITIALIZED;
  683.     newGrpPtr->y = UNINITIALIZED;
  684.     newGrpPtr->width = 0;
  685.     newGrpPtr->height = 0;
  686.     newGrpPtr->fileList = NULL;
  687.     newGrpPtr->groupBindings = NULL;
  688.     newGrpPtr->selectedP = FALSE;
  689.     newGrpPtr->highlightP = FALSE;
  690.     /*
  691.      * If this is too slow, then change this so it does not actually
  692.      * gather the files?
  693.      */
  694.     if (WishGatherSingleGroup(aWindow, newGrpPtr) != TCL_OK) {
  695.     /* eliminate group definition? */
  696.     free(newGrpPtr->rule);
  697.     return TCL_ERROR;
  698.     }
  699.  
  700.     return TCL_OK;
  701. }
  702.  
  703.  
  704. /*
  705.  *----------------------------------------------------------------------
  706.  *
  707.  * WishPrintTclError --
  708.  *
  709.  *    Print out a tcl interpreter error message.
  710.  *
  711.  * Results:
  712.  *    None.
  713.  *
  714.  * Side effects:
  715.  *    None.
  716.  *
  717.  *----------------------------------------------------------------------
  718.  */
  719. void
  720. WishPrintTclError(aWindow)
  721.     WishWindow    *aWindow;
  722. {
  723.     char    c;
  724.     char    stupidBuffer[TCL_RESULT_SIZE + 1];    /* I can't seem to
  725.                                 * print interpreter
  726.                              * result without
  727.                              * copying it! */
  728.  
  729.     /*
  730.      * Capitalize first character of error message.
  731.      */
  732.     c = aWindow->interp->result[0];
  733.     if ((c >= 'a') && (c <= 'z')) {
  734.     aWindow->interp->result[0] += 'A' - 'a';
  735.     }
  736.     strcpy(stupidBuffer, aWindow->interp->result, TCL_RESULT_SIZE);
  737.     /*
  738.      * output message - should call routine that uses 1-line window
  739.      * if possible.
  740.      */
  741.     aWindow->notifierP = TRUE;
  742.     Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  743.         stupidBuffer, NULL, TRUE, "Continue", (char *) NULL);
  744.     aWindow->notifierP = FALSE;
  745.     /* replace lower case */
  746.     aWindow->interp->result[0] = c;
  747.  
  748.     return;
  749. }
  750.  
  751.  
  752. /*
  753.  *----------------------------------------------------------------------
  754.  *
  755.  * WishDefineGroupCmd --
  756.  *
  757.  *    Add the definition of a new group.
  758.  *    Currently, this only will add it to the end of the list of groups.
  759.  *
  760.  * Syntax:
  761.  *    defineGroup defType def
  762.  *
  763.  * Results:
  764.  *    Returns TCL_OK if all went well, or TCL errors if not.
  765.  *
  766.  * Side effects:
  767.  *    A new group will be added.  It will not be displayed until something
  768.  *    causes a redisplay.
  769.  *
  770.  *----------------------------------------------------------------------
  771.  */
  772. int
  773. WishDefineGroupCmd(aWindow, interp, argc, argv)
  774.     WishWindow    *aWindow;
  775.     Tcl_Interp        *interp;
  776.     int            argc;
  777.     char        **argv;
  778. {
  779.     WishGroup    *grpPtr;
  780.     WishGroup    *newGrpPtr;
  781.  
  782.     if (argc != 3) {
  783.     sprintf(interp->result, "%s %s", "Wrong # of args. Must be 3 args,",
  784.         "\"defineGroup defType def\"");
  785.     return TCL_ERROR;
  786.     }
  787.  
  788.     for (grpPtr = aWindow->groupList; grpPtr != NULL;
  789.         grpPtr = grpPtr->nextPtr) {
  790.     if (strcmp(argv[2], grpPtr->rule) == 0) {
  791.         if (grpPtr->fileList == NULL && aWindow->hideEmptyGroupsP) {
  792.             sprintf(interp->result, "%s %s, %s",
  793.             "A group already has the definition", argv[2],
  794.             "but it may not be visible since no files match it.");
  795.         } else {
  796.         sprintf(interp->result, "A group already has the definition %s",
  797.             argv[2]);
  798.         }
  799.         return TCL_ERROR;
  800.     }
  801.     }
  802.  
  803.     newGrpPtr = (WishGroup *) malloc(sizeof (WishGroup));
  804.  
  805.     /* test the new group's definition */
  806.     if (GetNewGroup(aWindow, interp, argv + 1, newGrpPtr) != TCL_OK) {
  807.     free(newGrpPtr);
  808.     WishPrintTclError(aWindow);
  809.     WishDoCmd(aWindow, "close");
  810.     /*
  811.      * It seems weird to return with TCL_ERROR here, but if i don't,
  812.      * something will try to unmap the previously destroyed window.
  813.      * Strangely, nothing wrong seems to happen this way, such as
  814.      * something trying to print out a message in a deleted interpreter...
  815.      */
  816.     return TCL_ERROR;
  817.     }
  818.  
  819.     /* attach new group to end of list */
  820.     if (aWindow->groupList == NULL) {
  821.     aWindow->groupList = newGrpPtr;
  822.     } else {
  823.     for (grpPtr = aWindow->groupList; grpPtr->nextPtr != NULL;
  824.         grpPtr = grpPtr->nextPtr) {
  825.         /* nothing */
  826.     }
  827.     grpPtr->nextPtr = newGrpPtr;
  828.     }
  829.     if (aWindow->dontDisplayChangesP == FALSE) {
  830.     /* update display */
  831.     if (aWindow->firstElement == UNINITIALIZED) {
  832.         aWindow->firstElement = 1;
  833.     }
  834.     WishSetPositions(aWindow);
  835.     }
  836.     return TCL_OK;
  837. }
  838.  
  839.  
  840. /*
  841.  *----------------------------------------------------------------------
  842.  *
  843.  * WishSelectionCmd --
  844.  *
  845.  *    Return the current value of the selection set in interp->result.
  846.  *
  847.  * Syntax:
  848.  *    selection
  849.  *
  850.  * Results:
  851.  *    Returns TCL_OK if all went well, or TCL_ERROR if any sort of
  852.  *    error occurred.
  853.  *
  854.  * Side effects:
  855.  *    None except memory allocation.
  856.  *
  857.  *----------------------------------------------------------------------
  858.  */
  859. /*ARGSUSED*/
  860. int
  861. WishSelectionCmd(aWindow, interp, argc, argv)
  862.     WishWindow    *aWindow;
  863.     Tcl_Interp        *interp;
  864.     int            argc;
  865.     char        **argv;
  866. {
  867.     if (argc > 1) {
  868.     sprintf(interp->result, "Too many args to selection command.");
  869.     return TCL_ERROR;
  870.     }
  871.     return TCL_OK;
  872. }
  873.  
  874.  
  875. /*
  876.  *----------------------------------------------------------------------
  877.  *
  878.  * WishSortFilesCmd --
  879.  *
  880.  *    Add or change the method of sorting directory entries.
  881.  *
  882.  * Syntax:
  883.  *    changeSort [method]
  884.  *
  885.  * Results:
  886.  *    Returns TCL_OK if all went well, or TCL_ERROR if any sort of
  887.  *    error occurred.
  888.  *
  889.  * Side effects:
  890.  *    The order of the files displayed will change if the new sorting
  891.  *    method is different.  In this case, the user will be prompted
  892.  *    to see if he wishes to make the new sorting method the default
  893.  *    method for the directory.
  894.  *
  895.  *----------------------------------------------------------------------
  896.  */
  897. int
  898. WishSortFilesCmd(aWindow, interp, argc, argv)
  899.     WishWindow    *aWindow;
  900.     Tcl_Interp        *interp;
  901.     int            argc;
  902.     char        **argv;
  903. {
  904.     int    which;
  905.  
  906.     if (argc > 3) {
  907.     sprintf(interp->result, "Too many args: 3 arg maximum to sort command");
  908.     return TCL_ERROR;
  909.     }
  910.     if (argc == 1) {
  911.     /*
  912.      * Get the sorting method from the user.  It would be nice if this
  913.      * could all be in one notifier or in a check-list like window, but
  914.      * Sx_Notify puts all the buttons in a single line at the top of the
  915.      * notifier and there are too many buttons to fit on the window here
  916.      * if the "reverse" options are included.  So for now it's done with
  917.      * 2 notifiers, one to get what to sort by and the next to say
  918.      * forwards or backwards.
  919.      *
  920.      * Protect the data structure from redraws initiated in Sx_Notify.
  921.      */
  922.     aWindow->notifierP = TRUE;
  923.     which = Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  924.         "Pick sorting method", NULL, TRUE, "Alpha", "AccessTime",
  925.         "DataModifyTime", "DescriptorModifyTime", "Size",
  926.         (char *) NULL);
  927.     aWindow->notifierP = FALSE;
  928.     switch(which) {
  929.     case 0:
  930.         aWindow->sortingInstructions = WISH_ALPHA_SORT;
  931.         break;
  932.     case 1:
  933.         aWindow->sortingInstructions = WISH_ATIME_SORT;
  934.         break;
  935.     case 2:
  936.         aWindow->sortingInstructions = WISH_MTIME_SORT;
  937.         break;
  938.     case 3:
  939.         aWindow->sortingInstructions = WISH_DTIME_SORT;
  940.         break;
  941.     case 4:
  942.         aWindow->sortingInstructions = WISH_SIZE_SORT;
  943.         break;
  944.     default:
  945.         sprintf(wishErrorMsg, "%s %s", "Something is wrong.",
  946.             "The sorthing method just entered is unrecognized.");
  947.         aWindow->notifierP = TRUE;
  948.         Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  949.             wishErrorMsg, "Skip command", (char *) NULL);
  950.         aWindow->notifierP = FALSE;
  951.         return TCL_ERROR;
  952.     }
  953.     aWindow->notifierP = TRUE;
  954.     which = Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1, 0,
  955.         "Sort in forwards or reverse order?", NULL, TRUE,
  956.         "Forwards", "Reverse", (char *) NULL);
  957.     aWindow->notifierP = FALSE;
  958.     if (which == 1) {
  959.         aWindow->sortingInstructions |= WISH_REVERSE_SORT;
  960.     }
  961.     WishSetSort(aWindow, NULL, NULL);
  962.     } else if (argc == 2) {        /* parse command */
  963.     WishSetSort(aWindow, argv[1], NULL);
  964.     } else {
  965.     WishSetSort(aWindow, argv[1], argv[2]);
  966.     }
  967.     /*
  968.      * Now ask if they want to make this change be the default sort
  969.      * method for this directory.
  970.      */
  971.     /* soon. */
  972.  
  973.     if (aWindow->dontDisplayChangesP == FALSE) {
  974.     /* update display */
  975.     if (aWindow->firstElement == UNINITIALIZED) {
  976.         aWindow->firstElement = 1;
  977.     }
  978.     WishSetPositions(aWindow);
  979.     }
  980.  
  981.     return TCL_OK;
  982. }
  983.  
  984.  
  985. /*
  986.  *----------------------------------------------------------------------
  987.  *
  988.  * WishSetSort --
  989.  *
  990.  *    Change the sorting information and resort files.
  991.  *    If the reverse argument is non-null, do the reverse sort of the
  992.  *    sortMethod argument.  If the sortMethod argument is NULL, then the
  993.  *    aWindow->sortingInstructions field is already set.
  994.  *
  995.  * Results:
  996.  *    None.
  997.  *
  998.  * Side effects:
  999.  *    The order of the files displayed will change if the new sorting
  1000.  *    method is different.
  1001.  *
  1002.  *----------------------------------------------------------------------
  1003.  */
  1004. void
  1005. WishSetSort(aWindow, sortMethod, reverse)
  1006.     WishWindow    *aWindow;
  1007.     char        *sortMethod;
  1008.     char        *reverse;
  1009. {
  1010.     int        getAttrsP = FALSE;
  1011.     WishFile    *tmpPtr;
  1012.     WishGroup    *grpPtr;
  1013.     int        (*compareProc)();
  1014.     WishFile    **fileArray;
  1015.     int        i, arraySize;
  1016.  
  1017.     if (sortMethod != NULL) {
  1018.     aWindow->sortingInstructions = 0;
  1019.     if (reverse != NULL) {
  1020.         aWindow->sortingInstructions |= WISH_REVERSE_SORT;
  1021.     }
  1022.     if (strcmp(sortMethod, "alpha") == 0 ||
  1023.         strcmp(sortMethod, "Alpha") == 0) {
  1024.         aWindow->sortingInstructions |= WISH_ALPHA_SORT;
  1025.     }
  1026.     if (strcmp(sortMethod, "accessTime") == 0 ||
  1027.         strcmp(sortMethod, "AccessTime") == 0 ||
  1028.         strcmp(sortMethod, "atime") == 0 ||
  1029.         strcmp(sortMethod, "aTime") == 0 ||
  1030.         strcmp(sortMethod, "Atime") == 0) {
  1031.         aWindow->sortingInstructions |= WISH_ATIME_SORT;
  1032.     }
  1033.     if (strcmp(sortMethod, "modifyTime") == 0 ||
  1034.         strcmp(sortMethod, "ModifyTime") == 0 ||
  1035.         strcmp(sortMethod, "datamodtime") == 0 ||
  1036.         strcmp(sortMethod, "dataModTime") == 0 ||
  1037.         strcmp(sortMethod, "DataModTime") == 0 ||
  1038.         strcmp(sortMethod, "datamodifytime") == 0 ||
  1039.         strcmp(sortMethod, "dataModifyTime") == 0 ||
  1040.         strcmp(sortMethod, "DataModifyTime") == 0 ||
  1041.         strcmp(sortMethod, "mtime") == 0 ||
  1042.         strcmp(sortMethod, "mTime") == 0 ||
  1043.         strcmp(sortMethod, "Mtime") == 0) {
  1044.         aWindow->sortingInstructions |= WISH_MTIME_SORT;
  1045.     }
  1046.     if (strcmp(sortMethod, "descModifyTime") == 0 ||
  1047.         strcmp(sortMethod, "DescModifyTime") == 0 ||
  1048.         strcmp(sortMethod, "descmodifytime") == 0 ||
  1049.         strcmp(sortMethod, "descmodtime") == 0 ||
  1050.         strcmp(sortMethod, "descModTime") == 0 ||
  1051.         strcmp(sortMethod, "DescModTime") == 0 ||
  1052.         strcmp(sortMethod, "descriptormodifytime") == 0 ||
  1053.         strcmp(sortMethod, "descriptorModifyTime") == 0 ||
  1054.         strcmp(sortMethod, "DescriptorModifyTime") == 0 ||
  1055.         strcmp(sortMethod, "dtime") == 0 ||
  1056.         strcmp(sortMethod, "dTime") == 0 ||
  1057.         strcmp(sortMethod, "Dtime") == 0) {
  1058.         aWindow->sortingInstructions |= WISH_DTIME_SORT;
  1059.     }
  1060.     if (strcmp(sortMethod, "size") == 0 ||
  1061.         strcmp(sortMethod, "Size") == 0) {
  1062.         aWindow->sortingInstructions |= WISH_SIZE_SORT;
  1063.     }
  1064.     }
  1065.  
  1066.     /* Now sort the files -- get attr's if necessary */
  1067.     getAttrsP = WISH_ATTR_NECESSARY_P;
  1068.     if (aWindow->groupList == NULL) {
  1069.     return;
  1070.     }
  1071.     /* need comparison function that takes ptrs to WishFiles */
  1072.     WishGetCompareProc(aWindow, &compareProc, TRUE);
  1073.     for (grpPtr = aWindow->groupList; grpPtr != NULL;
  1074.         grpPtr = grpPtr->nextPtr) {
  1075.     /* if 0 or 1 files, don't sort */
  1076.     if (grpPtr->fileList == NULL || grpPtr->fileList->nextPtr == NULL) {
  1077.         continue;
  1078.     }
  1079.     for (i = 0, tmpPtr = grpPtr->fileList; tmpPtr != NULL;
  1080.         tmpPtr = tmpPtr->nextPtr, i++) {
  1081.         if (getAttrsP && tmpPtr->attrPtr == NULL) {
  1082.         tmpPtr->attrPtr = (struct stat *)
  1083.             malloc(sizeof (struct stat));
  1084.         if (lstat(tmpPtr->name, tmpPtr->attrPtr) != 0) {
  1085.             /* skip this file */
  1086.             sprintf(wishErrorMsg, "%s %s.",
  1087.                 "Couldn't get attributes for file", tmpPtr->name);
  1088.             aWindow->notifierP = TRUE;
  1089.             Sx_Notify(wishDisplay, aWindow->surroundingWindow, -1, -1,
  1090.                 0, wishErrorMsg, NULL, TRUE, "Continue",
  1091.                 (char *) NULL);
  1092.             aWindow->notifierP = FALSE;
  1093.             bzero((char *) tmpPtr->attrPtr, sizeof (struct stat));
  1094.         }
  1095.         }
  1096.     }
  1097.     arraySize = i;
  1098.     fileArray = (WishFile **) malloc(arraySize *
  1099.         sizeof (WishFile *));
  1100.     for (tmpPtr = grpPtr->fileList, i = 0; tmpPtr != NULL;
  1101.         tmpPtr = tmpPtr->nextPtr, i++) {
  1102.         fileArray[i] = tmpPtr;
  1103.     }
  1104.     qsort(fileArray, arraySize, sizeof (WishFile *), compareProc);
  1105.     for (i = 0; i < arraySize - 1; i++) {
  1106.         fileArray[i]->nextPtr = fileArray[i+1];
  1107.     }
  1108.     fileArray[arraySize - 1]->nextPtr = NULL;
  1109.     grpPtr->fileList = fileArray[0];
  1110.     free(fileArray);
  1111.     }
  1112.  
  1113.     return;
  1114. }
  1115.  
  1116.  
  1117.  
  1118. /*
  1119.  *----------------------------------------------------------------------
  1120.  *
  1121.  * WishCloseCmd --
  1122.  *
  1123.  *    Close the window.  This should do some more cleaning up.
  1124.  *
  1125.  * Syntax:
  1126.  *    close
  1127.  *
  1128.  * Results:
  1129.  *    TCL_OK.
  1130.  *
  1131.  * Side effects:
  1132.  *    Closes the window, deletes the Tcl interpreter for the window, and
  1133.  *    frees up the window data structures.  If this was the last window,
  1134.  *    we may exit.
  1135.  *
  1136.  *----------------------------------------------------------------------
  1137.  */
  1138. /*ARGSUSED*/
  1139. int
  1140. WishCloseCmd(aWindow, interp, argc, argv)
  1141.     register    WishWindow    *aWindow;
  1142.     Tcl_Interp    *interp;
  1143.     int        argc;
  1144.     char    **argv;
  1145. {
  1146.     if (!MonClient_DeleteDir(aWindow->dir,
  1147.         (ClientData) aWindow->surroundingWindow)) {
  1148.     /* what should I do here?  Does it matter? */
  1149.     }
  1150.     XDeleteContext(wishDisplay, aWindow->surroundingWindow,
  1151.         wishWindowContext);
  1152.     /* DeleteHandlers? */
  1153.     WishGarbageCollect(aWindow);
  1154.     XDestroyWindow(wishDisplay, aWindow->surroundingWindow);
  1155.     Tcl_DeleteInterp(aWindow->interp);
  1156.     free(aWindow);
  1157.     wishWindowCount--;
  1158.     if (wishWindowCount <= 0) {
  1159.     exit(0);
  1160.     }
  1161.     return TCL_OK;
  1162. }
  1163.  
  1164.  
  1165. /*
  1166.  *----------------------------------------------------------------------
  1167.  *
  1168.  * WishExecCmd --
  1169.  *
  1170.  *    Execute a command in an associated shell window.
  1171.  *
  1172.  * Syntax:
  1173.  *    exec command
  1174.  *
  1175.  * Results:
  1176.  *    Returns TCL_OK if all went well, or TCL_ERROR if an associated
  1177.  *    shell window could not be found or there was no shell command
  1178.  *    given.  Whether or not the command
  1179.  *    given to the shell executes happily is another matter.  Maybe I'll
  1180.  *    decide that its return status should be available, but I don't know
  1181.  *    how to do that...
  1182.  *
  1183.  * Side effects:
  1184.  *    Almost anything -- it depends what the shell command does.
  1185.  *
  1186.  *----------------------------------------------------------------------
  1187.  */
  1188. /*ARGSUSED*/
  1189. int
  1190. WishExecCmd(aWindow, interp, argc, argv)
  1191.     WishWindow    *aWindow;
  1192.     Tcl_Interp    *interp;
  1193.     int        argc;
  1194.     char    **argv;
  1195. {
  1196.     int        i;
  1197.     char    *command;
  1198.     int        length;
  1199.     int        result;
  1200.  
  1201.     length = argc - 1;    /* spaces between command words + insert word */
  1202.     for (i = 1; i < argc; i++) {    /* skip first "exec" word */
  1203.     length += strlen(argv[i]);
  1204.     }
  1205.     length += strlen("insert");
  1206.     command = (char *) malloc(length + 1);    /* plus null char */
  1207.     strcpy(command, "insert");
  1208.     for (i = 1; i < argc; i++) {    /* skip first "exec" word */
  1209.     strcat(command, " ");
  1210.     strcat(command, argv[i]);
  1211.     }
  1212.     result = Tx_Command(wishDisplay, aWindow->txOutsideWindow, command);
  1213.     free(command);
  1214.  
  1215.     return result;
  1216. }
  1217.  
  1218.  
  1219. /*
  1220.  *----------------------------------------------------------------------
  1221.  *
  1222.  * WishGroupBindCmd --
  1223.  *
  1224.  *    Add a command binding to a group.  This will bind a command
  1225.  *    to a particular button (or button combination).
  1226.  *
  1227.  * Syntax:
  1228.  *    groupbind groupname buttonMask command
  1229.  *
  1230.  * Results:
  1231.  *    Returns TCL_OK if all went well, or TCL errors if not.
  1232.  *
  1233.  * Side effects:
  1234.  *    A new command binding will be added to the group.
  1235.  *
  1236.  *----------------------------------------------------------------------
  1237.  */
  1238. int
  1239. WishGroupBindCmd(aWindow, interp, argc, argv)
  1240.     WishWindow    *aWindow;
  1241.     Tcl_Interp        *interp;
  1242.     int            argc;
  1243.     char        **argv;
  1244. {
  1245.     WishGroup    *grpPtr;
  1246.     char    **buttonArgv;
  1247.     int        buttonArgc;
  1248.     int        button = 0;
  1249.     int        test;
  1250.     int        i;
  1251.  
  1252.     if (argc != 4) {
  1253.     sprintf(interp->result,
  1254.         "Wrong # of args to groupBind command, %s",
  1255.         "\"groupBind groupName buttonMask command\"");
  1256.     return TCL_ERROR;
  1257.     }
  1258.     for (grpPtr = aWindow->groupList; grpPtr != NULL;
  1259.         grpPtr = grpPtr->nextPtr) {
  1260.     if (strcmp(grpPtr->rule, argv[1]) == 0) {
  1261.         break;
  1262.     }
  1263.     }
  1264.     if (grpPtr == NULL) {
  1265.     sprintf(interp->result, "No such group %s", argv[1]);
  1266.     return TCL_ERROR;
  1267.     }
  1268.  
  1269.     if (Tcl_SplitList(interp, argv[2], &buttonArgc, &buttonArgv) != TCL_OK) {
  1270.     return TCL_ERROR;
  1271.     }
  1272.     for (i = 0; i < buttonArgc; i++) {
  1273.     test = WishWhichButton(buttonArgv[i]);
  1274.     if (test == 0) {
  1275.         sprintf(interp->result, "Bad button name %s", argv[i]);
  1276.         /* will this really free it?  Tcl man page says so... */
  1277.         free(buttonArgv);
  1278.         return TCL_ERROR;
  1279.     }
  1280.     button |= test;
  1281.     }
  1282.     /* will this really free it?  Tcl man page says so... */
  1283.     free(buttonArgv);
  1284.     WishAddGroupBinding(grpPtr, button, argv[3]);
  1285.  
  1286.     return TCL_OK;
  1287. }
  1288.  
  1289.  
  1290. /*
  1291.  *----------------------------------------------------------------------
  1292.  *
  1293.  * WishMenuCmd --
  1294.  *
  1295.  *    Create, delete, and modify menus.
  1296.  *
  1297.  * Syntax:
  1298.  *    menu append name leftText centerText rightText color cmd
  1299.  *    menu create name leftText centerText rightText color cmd leftText ...
  1300.  *    menu delete name
  1301.  *    menu modify name entryIndex leftText centerText rightText color cmd
  1302.  *
  1303.  * Results:
  1304.  *    Returns TCL_OK if all went well, or TCL_ERROR if any sort of
  1305.  *    error occurred.
  1306.  *
  1307.  * Side effects:
  1308.  *    The menu structure for the current window gets modified.
  1309.  *
  1310.  *----------------------------------------------------------------------
  1311.  */
  1312. int
  1313. WishMenuCmd(aWindow, interp, argc, argv)
  1314.     register    WishWindow    *aWindow;
  1315.     Tcl_Interp    *interp;
  1316.     int        argc;
  1317.     char    **argv;
  1318. {
  1319. #ifdef NOTDEF
  1320.     MxMenuInfo *miPtr;
  1321. #endif NOTDEF
  1322.     int length;
  1323.     Sx_MenuEntry entries[SX_MAX_MENU_ENTRIES];
  1324.  
  1325.     extern char *GetString();        /* Forward references */
  1326.  
  1327.     if (argc < 2) {
  1328.     sprintf(interp->result, "wrong # args: must be \"%.50s option [args]\"",
  1329.         argv[0]);
  1330.     return TCL_ERROR;
  1331.     }
  1332.     length = strlen(argv[1]);
  1333.     if (strncmp(argv[1], "append", length) == 0) {
  1334.     Window window;
  1335.     XFontStruct *fontPtr;
  1336.     int numEntries;
  1337.     unsigned long fg, bg;
  1338.  
  1339.     if (argc != 8) {
  1340.         sprintf(interp->result, "wrong # args: should be \"%.50s append name left center right color cmd\"",
  1341.             argv[0]);
  1342.         return TCL_ERROR;
  1343.     }
  1344.     window = Sx_MenuGetWindow(wishDisplay, aWindow->menuBar, argv[2]);
  1345.     if (window == NULL) {
  1346.         goto menuNameBad;
  1347.     }
  1348.     numEntries = Sx_MenuGetInfo(wishDisplay, window, entries, &fontPtr,
  1349.         &fg, &bg);
  1350.     if (numEntries >= SX_MAX_MENU_ENTRIES) {
  1351.         return TCL_OK;
  1352.     }
  1353.     entries[numEntries].leftText = GetString(argv[3]);
  1354.     entries[numEntries].centerText = GetString(argv[4]);
  1355.     entries[numEntries].rightText = GetString(argv[5]);
  1356.     entries[numEntries].background =
  1357.         Util_StringToColor(wishDisplay, argv[6]);
  1358. /* should check to see if it returns -1 value!!!! */
  1359.     entries[numEntries].proc = WishMenuProc;
  1360.     /* Mx uses a structure with both command AND aWindow fields.  Should I? */
  1361.     entries[numEntries].clientData = (ClientData) Util_Strcpy(NULL,
  1362.         argv[7]);
  1363.     Sx_MenuCreate(wishDisplay, aWindow->menuBar, argv[2], numEntries+1,
  1364.         entries, fontPtr, fg, bg);
  1365.     return TCL_OK;
  1366.     }
  1367.     if (strncmp(argv[1], "create", length) == 0) {
  1368.     int numEntries, i, arg;
  1369.  
  1370.     numEntries = (argc - 3)/5;
  1371.     if ((argc-3) != (numEntries*5)) {
  1372.         sprintf(interp->result, "wrong # args: should be \"%.50s create name [left center right color cmd] ...\"",
  1373.             argv[0]);
  1374.         return TCL_ERROR;
  1375.     }
  1376.     if (numEntries > SX_MAX_MENU_ENTRIES) {
  1377.         sprintf(interp->result,
  1378.             "can't create a menu with more than %d entries",
  1379.             SX_MAX_MENU_ENTRIES);
  1380.         return TCL_ERROR;
  1381.     }
  1382.  
  1383.     for (i = 0, arg = 3; i < numEntries; i++, arg += 5) {
  1384.         entries[i].leftText = GetString(argv[arg]);
  1385.         entries[i].centerText = GetString(argv[arg+1]);
  1386.         entries[i].rightText = GetString(argv[arg+2]);
  1387.         entries[i].background =
  1388.             Util_StringToColor(wishDisplay, argv[arg+3]);
  1389. /* should check to see if it returns -1 value! */
  1390.         entries[i].proc = WishMenuProc;
  1391.         entries[i].clientData = (ClientData) Util_Strcpy(NULL, argv[arg+4]);
  1392.     }
  1393.     Sx_MenuCreate(wishDisplay, aWindow->menuBar, argv[2], numEntries,
  1394.         entries, aWindow->fontPtr, aWindow->menuForeground,
  1395.         aWindow->menuBackground);
  1396.     return TCL_OK;
  1397.     } else if (strncmp(argv[1], "delete",length) == 0) {
  1398.     Window window;
  1399.     int count;
  1400.  
  1401.     if (argc != 3) {
  1402.         sprintf(interp->result,
  1403.             "wrong # args: should be \"%.50s delete name\"",
  1404.             argv[0]);
  1405.         return TCL_ERROR;
  1406.     }
  1407.     window = Sx_MenuGetWindow(wishDisplay, aWindow->menuBar, argv[2]);
  1408.     if (window == NULL) {
  1409.         goto menuNameBad;
  1410.     }
  1411.     count = Sx_MenuGetInfo(wishDisplay, window, entries,
  1412.         (XFontStruct **) NULL, (int *) NULL, (int *) NULL);
  1413.     for (count--; count >= 0; count--) {
  1414.         free(entries[count].clientData);
  1415.     }
  1416.     XDestroyWindow(wishDisplay, window);
  1417.     return TCL_OK;
  1418. #ifdef NOTDEF
  1419.     } else if (strncmp(argv[1], "info", length) == 0) {
  1420.     Window window;
  1421.     int count, i;
  1422.     char *names[SX_MAX_MENUS];
  1423.     char *entryStrings[SX_MAX_MENU_ENTRIES];
  1424.     char *pieces[4];
  1425.  
  1426.     if (argc == 2) {
  1427.         count = Sx_MenuGetNames(mxwPtr->display, mxwPtr->menuBar, names,
  1428.             (Window *) NULL);
  1429.         interp->result = Tcl_Merge(count, names);
  1430.         interp->dynamic = 1;
  1431.         return TCL_OK;
  1432.     }
  1433.     if (argc != 3) {
  1434.         sprintf(interp->result,
  1435.             "wrong # args: should be \"%.50s info [name]\"",
  1436.             argv[0]);
  1437.         return TCL_ERROR;
  1438.     }
  1439.     window = Sx_MenuGetWindow(mxwPtr->display, mxwPtr->menuBar, argv[2]);
  1440.     if (window == NULL) {
  1441.         goto menuNameBad;
  1442.     }
  1443.     count = Sx_MenuGetInfo(mxwPtr->display, window, entries,
  1444.         (XFontStruct **) NULL, (unsigned long *) NULL,
  1445.         (unsigned long *) NULL);
  1446.     for (i = 0; i < count; i++) {
  1447.         pieces[0] = entries[i].leftText;
  1448.         if (pieces[0] == NULL) {
  1449.         pieces[0] = "";
  1450.         }
  1451.         pieces[1] = entries[i].centerText;
  1452.         if (pieces[1] == NULL) {
  1453.         pieces[1] = "";
  1454.         }
  1455.         pieces[2] = entries[i].rightText;
  1456.         if (pieces[2] == NULL) {
  1457.         pieces[2] = "";
  1458.         }
  1459.         pieces[3] = ((MxMenuInfo *) entries[i].clientData)->command;
  1460.         if (pieces[3] == NULL) {
  1461.         pieces[3] = "";
  1462.         }
  1463.         entryStrings[i] = Tcl_Merge(4, pieces);
  1464.     }
  1465.     interp->result = Tcl_Merge(count, entryStrings);
  1466.     interp->dynamic = 1;
  1467.     for (i = 0; i < count; i++) {
  1468.         free(entryStrings[i]);
  1469.     }
  1470.     return TCL_OK;
  1471. #endif NOTDEF
  1472.     } else if (strncmp(argv[1], "modify", length) == 0) {
  1473.     Window window;
  1474.     Sx_MenuEntry entry;
  1475.     int index;
  1476.  
  1477.     if (argc != 9) {
  1478.         sprintf(interp->result, "wrong # args: should be \"%.50s modify name index left center right color cmd\"",
  1479.             argv[0]);
  1480.         return TCL_ERROR;
  1481.     }
  1482.     window = Sx_MenuGetWindow(wishDisplay, aWindow->menuBar, argv[2]);
  1483.     if (window == NULL) {
  1484.         goto menuNameBad;
  1485.     }
  1486.     index = atoi(argv[3]);
  1487.     if ((index < 0) || (index >= Sx_MenuGetInfo(wishDisplay, window,
  1488.         entries, (XFontStruct **) NULL, (int *) NULL, (int *) NULL))) {
  1489.         sprintf(interp->result,
  1490.             "there's no entry %d in menu \"%.50s\"",
  1491.             index, argv[2]);
  1492.         return TCL_ERROR;
  1493.     }
  1494.     free(entries[index].clientData);
  1495.     entry.leftText = GetString(argv[4]);
  1496.     entry.centerText = GetString(argv[5]);
  1497.     entry.rightText = GetString(argv[6]);
  1498. /* should check to see if it returns -1 value! */
  1499.     entry.background = Util_StringToColor(wishDisplay, argv[7]);
  1500.     entry.proc = WishMenuProc;
  1501.     entry.clientData = (ClientData) Util_Strcpy(NULL, argv[8]);
  1502.     Sx_MenuReplaceEntry(wishDisplay, window, index, &entry);
  1503.     return TCL_OK;
  1504.     } else {
  1505.     sprintf(interp->result, "bad \"%.50s\" option: must be append, create, delete, or modify\"",
  1506.         argv[0]);
  1507.     return TCL_ERROR;
  1508.     }
  1509.  
  1510.     menuNameBad:
  1511.     sprintf(interp->result, "there's no menu named \"%.50s\".", argv[2]);
  1512.     return TCL_ERROR;
  1513. }
  1514.  
  1515.  
  1516.  
  1517. /*
  1518.  *----------------------------------------------------------------------
  1519.  *
  1520.  * WishOpenCmd --
  1521.  *
  1522.  *    Create another wish window.
  1523.  *    Eventually this will be create another Wish window, with an
  1524.  *    argument to say whether it should be a flat or tree window.  If
  1525.  *    the argument is not supplied, it should default to the type of
  1526.  *    window where the command was called from.
  1527.  *
  1528.  * Syntax:
  1529.  *    open directory
  1530.  *
  1531.  * Results:
  1532.  *    Returns TCL_OK if all went well, various TCL errors if not.
  1533.  *
  1534.  * Side effects:
  1535.  *    A new window should be created.
  1536.  *
  1537.  *----------------------------------------------------------------------
  1538.  */
  1539. int
  1540. WishOpenCmd(aWindow, interp, argc, argv)
  1541.     WishWindow    *aWindow;
  1542.     Tcl_Interp        *interp;
  1543.     int            argc;
  1544.     char        **argv;
  1545. {
  1546.     if (argc > 2) {
  1547.     sprintf(interp->result, "%s %s", "Too many args to open command:",
  1548.         "open [directory]");
  1549.     return TCL_ERROR;
  1550.     }
  1551.     if (argc == 2) {
  1552.     if (WishCreate(aWindow, argv[1]) == NULL) {
  1553.         return TCL_ERROR;
  1554.     }
  1555.     } else if (WishCreate(aWindow, NULL) == NULL) {
  1556.     return TCL_ERROR;
  1557.     }
  1558.  
  1559.     return TCL_OK;
  1560. }
  1561.  
  1562.  
  1563. /*
  1564.  *----------------------------------------------------------------------
  1565.  *
  1566.  * WishPatternCompareCmd --
  1567.  *
  1568.  *    Compare two strings.  In the interpreter, return 0 for a match,
  1569.  *    and < 0 for an error.  Return > 0 for failure to match.
  1570.  *
  1571.  * Syntax:
  1572.  *    pattern    string1 string2
  1573.  *
  1574.  * Results:
  1575.  *    TCL_OK if everything went okay, TCL_ERROR if not.
  1576.  *
  1577.  * Side effects:
  1578.  *    None.
  1579.  *
  1580.  *----------------------------------------------------------------------
  1581.  */
  1582. /*ARGSUSED*/
  1583. int
  1584. WishPatternCompareCmd(aWindow, interp, argc, argv)
  1585.     register    WishWindow    *aWindow;
  1586.     Tcl_Interp    *interp;
  1587.     int        argc;
  1588.     char    **argv;
  1589. {
  1590.     int    result;
  1591.  
  1592.     if (argc != 3) {
  1593.     sprintf(interp->result, "pattern command requires 3 args");
  1594.     return TCL_ERROR;
  1595.     }
  1596.     result = Pattern_Match(argv[1], argv[2]);
  1597.     sprintf(interp->result, "%d", result);
  1598.  
  1599.     return TCL_OK;
  1600. }
  1601.  
  1602.  
  1603. /*
  1604.  *----------------------------------------------------------------------
  1605.  *
  1606.  * WishQuitCmd --
  1607.  *
  1608.  *    Exit the program.
  1609.  *
  1610.  * Syntax:
  1611.  *    quit
  1612.  *
  1613.  * Results:
  1614.  *    Exits.
  1615.  *
  1616.  * Side effects:
  1617.  *    Exits.
  1618.  *
  1619.  *----------------------------------------------------------------------
  1620.  */
  1621. /*ARGSUSED*/
  1622. int
  1623. WishQuitCmd(aWindow, interp, argc, argv)
  1624.     register    WishWindow    *aWindow;
  1625.     Tcl_Interp    *interp;
  1626.     int        argc;
  1627.     char    **argv;
  1628. {
  1629.     /*
  1630.      * I should go through and call MonClient_DeleteDir for each remaining 
  1631.      * window.
  1632.      */
  1633.     exit(0);
  1634. }
  1635.  
  1636. #ifdef NOTDEF
  1637.  
  1638. /*
  1639.  *----------------------------------------------------------------------
  1640.  *
  1641.  * WishRestartCmd --
  1642.  *
  1643.  *    Resource the startup files and rebuild the display of the current
  1644.  *    directory.
  1645.  *
  1646.  * Syntax:
  1647.  *    restart
  1648.  *
  1649.  * Results:
  1650.  *    Returns TCL_OK if all went well, or TCL_ERROR if any sort of
  1651.  *    error occurred.
  1652.  *
  1653.  * Side effects:
  1654.  *    The display may change if the startup files have changed.
  1655.  *
  1656.  *----------------------------------------------------------------------
  1657.  */
  1658. int
  1659. WishRestartCmd(aWindow, interp, argc, argv)
  1660.     WishWindow    *aWindow;
  1661.     int            argc;
  1662.     char        **argv;
  1663. {
  1664.     if (argc != 1) {
  1665.     sprintf(interp->result, "too many args to restart command. 1 arg max");
  1666.     return TCL_ERROR;
  1667.     }
  1668.     WishGarbageCollect(aWindow);
  1669.     /* delete interpreter and start new one? */
  1670.     if (WishGatherNames(aWindow) != TCL_OK) {
  1671.     /* Fix here too. */
  1672.     }
  1673.     /* should it repick the size here if aWindow->pickSizeP is true? */
  1674.     aWindow->firstElement = 1;
  1675.     WishSetPositions(aWindow);
  1676.     /* WishRedraw will be called from event caused in WishSetPositions() */
  1677.  
  1678.     return TCL_OK;
  1679. }
  1680. #endif NOTDEF
  1681.  
  1682.  
  1683. /*
  1684.  *----------------------------------------------------------------------
  1685.  *
  1686.  * WishRedrawCmd --
  1687.  *
  1688.  *    Redraw the window.
  1689.  *
  1690.  * Syntax:
  1691.  *    redraw
  1692.  *
  1693.  * Results:
  1694.  *    TCL_OK.
  1695.  *
  1696.  * Side effects:
  1697.  *    Redraws the window.
  1698.  *
  1699.  *----------------------------------------------------------------------
  1700.  */
  1701. /*ARGSUSED*/
  1702. int
  1703. WishRedrawCmd(aWindow, interp, argc, argv)
  1704.     register    WishWindow    *aWindow;
  1705.     Tcl_Interp    *interp;
  1706.     int        argc;
  1707.     char    **argv;
  1708. {
  1709.     if (aWindow->dontDisplayChangesP == FALSE) {
  1710.     WishRedraw(aWindow);
  1711.     }
  1712.     return TCL_OK;
  1713. }
  1714.  
  1715.  
  1716. /*
  1717.  *----------------------------------------------------------------------
  1718.  *
  1719.  * WishResizeCmd --
  1720.  *
  1721.  *    Resize the window.
  1722.  *
  1723.  * Syntax:
  1724.  *    redraw newheight newwidth
  1725.  *
  1726.  * Results:
  1727.  *    TCL_OK if everything goes well, TCL_ERROR if not.
  1728.  *
  1729.  * Side effects:
  1730.  *    Resizes the window.
  1731.  *
  1732.  *----------------------------------------------------------------------
  1733.  */
  1734. int
  1735. WishResizeCmd(aWindow, interp, argc, argv)
  1736.     register    WishWindow    *aWindow;
  1737.     Tcl_Interp    *interp;
  1738.     int        argc;
  1739.     char    **argv;
  1740. {
  1741.     int    height, width;
  1742.     char    *cptr;
  1743.  
  1744.     if (argc != 3) {
  1745.     sprintf(interp->result, "Wrong # of args to resize command: %s",
  1746.         "\"resize newheight newwidth\"");
  1747.     return TCL_ERROR;
  1748.     }
  1749.     if ((height = strtol(argv[1], &cptr, 10)) == 0 && cptr == argv[1]) {
  1750.     sprintf(interp->result, "Bad height arg to resize command: %s",
  1751.         argv[1]);
  1752.     return TCL_ERROR;
  1753.     }
  1754.     if ((width = strtol(argv[2], &cptr, 10)) == 0 && cptr == argv[2]) {
  1755.     sprintf(interp->result, "Bad width arg to resize command: %s", argv[2]);
  1756.     return TCL_ERROR;
  1757.     }
  1758.     
  1759.     WishSetWindowAndRowInfo(aWindow, height, width);
  1760.  
  1761.     if (aWindow->dontDisplayChangesP == FALSE) {
  1762.     /* update display */
  1763.     if (aWindow->firstElement == UNINITIALIZED) {
  1764.         aWindow->firstElement = 1;
  1765.     }
  1766.     WishSetPositions(aWindow);
  1767.     /*
  1768.      * WishRedraw will be called from event caused in WishSetPostions().
  1769.      */
  1770.     }
  1771.  
  1772.     return TCL_OK;
  1773. }
  1774.  
  1775.  
  1776. /*
  1777.  *----------------------------------------------------------------------
  1778.  *
  1779.  * WishToggleSelEntryCmd --
  1780.  *
  1781.  *    Toggle the selection status of the given entry.
  1782.  *
  1783.  * Syntax:
  1784.  *    toggleSelectionEntry x y [wholeLine]
  1785.  *
  1786.  * Results:
  1787.  *    TCL_OK if everything went well.  TCL_ERROR if not.
  1788.  *
  1789.  * Side effects:
  1790.  *    Toggles the chosen entry.
  1791.  *
  1792.  *----------------------------------------------------------------------
  1793.  */
  1794. /*ARGSUSED*/
  1795. int
  1796. WishToggleSelEntryCmd(aWindow, interp, argc, argv)
  1797.     register    WishWindow    *aWindow;
  1798.     Tcl_Interp    *interp;
  1799.     int        argc;
  1800.     char    **argv;
  1801. {
  1802.     int        x, y;
  1803.     WishFile    *filePtr;
  1804.     WishGroup    *groupPtr = NULL;
  1805.     int    lineP = 0;
  1806.     char    *cptr;
  1807.  
  1808.     if (argc < 3 || argc > 4) {
  1809.     sprintf(aWindow->interp->result, "Wrong # of args to toggleSelection");
  1810.     return TCL_ERROR;
  1811.     }
  1812.     if ((x = strtol(argv[1], &cptr, 10)) == 0 && cptr == argv[1]) {
  1813.     sprintf(aWindow->interp->result, "Bad window x coordinate %s", argv[1]);
  1814.     return TCL_ERROR;
  1815.     }
  1816.     if ((y = strtol(argv[2], &cptr, 10)) == 0 && cptr == argv[2]) {
  1817.     sprintf(aWindow->interp->result, "Bad window y coordinate %s", argv[2]);
  1818.     return TCL_ERROR;
  1819.     }
  1820.     if (argc == 4) {
  1821.     if ((lineP = strtol(argv[3], &cptr, 10)) == 0 && cptr == argv[3]) {
  1822.         sprintf(aWindow->interp->result, "Bad 3rd arg to toggleSelection");
  1823.         return TCL_ERROR;
  1824.     }
  1825.     }
  1826.     
  1827.     filePtr = WishMapCoordsToFile(aWindow, x, y);
  1828.     if (filePtr == NULL && groupPtr == NULL) {
  1829.     sprintf(aWindow->interp->result,
  1830.         "No entry to select at those coordinates: %d %d", x, y);
  1831.     return TCL_ERROR;
  1832.     }
  1833.     if (filePtr != NULL) {
  1834.     WishChangeSelection(aWindow, (ClientData) filePtr, TRUE, lineP, TRUE);
  1835.     } else {
  1836.     WishChangeSelection(aWindow, (ClientData) groupPtr, FALSE, FALSE,
  1837.         TRUE);
  1838.     }
  1839.  
  1840.     return TCL_OK;
  1841. }
  1842.  
  1843. /*
  1844.  *----------------------------------------------------------------------
  1845.  *
  1846.  * WishToggleSelectionCmd --
  1847.  *
  1848.  *    Select or deselect given file.
  1849.  *
  1850.  * Syntax:
  1851.  *    toggleSelection x y [wholeLine]
  1852.  *
  1853.  * Results:
  1854.  *    TCL_OK if everything went well.  TCL_ERROR if not.
  1855.  *
  1856.  * Side effects:
  1857.  *    Changes the selection variable to be given file or empty.
  1858.  *
  1859.  *----------------------------------------------------------------------
  1860.  */
  1861. int
  1862. WishToggleSelectionCmd(aWindow, interp, argc, argv)
  1863.     register    WishWindow    *aWindow;
  1864.     Tcl_Interp    *interp;
  1865.     int        argc; char    **argv;
  1866. {
  1867.     int        x, y;
  1868.     WishFile    *filePtr = NULL;
  1869.     WishGroup    *groupPtr = NULL;        /* not used yet */
  1870.     int    lineP = 0;
  1871.     char    *cptr;
  1872.  
  1873.     if (argc < 3 || argc > 4) {
  1874.     sprintf(aWindow->interp->result, "Wrong # of args to toggleSelection");
  1875.     return TCL_ERROR;
  1876.     }
  1877.     if ((x = strtol(argv[1], &cptr, 10)) == 0 && cptr == argv[1]) {
  1878.     sprintf(aWindow->interp->result, "Bad window x coordinate %s", argv[1]);
  1879.     return TCL_ERROR;
  1880.     }
  1881.     if ((y = strtol(argv[2], &cptr, 10)) == 0 && cptr == argv[2]) {
  1882.     sprintf(aWindow->interp->result, "Bad window y coordinate %s", argv[2]);
  1883.     return TCL_ERROR;
  1884.     }
  1885.     if (argc == 4) {
  1886.     if ((lineP = strtol(argv[3], &cptr, 10)) == 0 && cptr == argv[3]) {
  1887.         sprintf(aWindow->interp->result, "Bad 3rd arg to toggleSelection");
  1888.         return TCL_ERROR;
  1889.     }
  1890.     }
  1891.     
  1892.     filePtr = WishMapCoordsToFile(aWindow, x, y);
  1893.     if (filePtr == NULL && groupPtr == NULL) {
  1894.     sprintf(aWindow->interp->result,
  1895.         "No entry to select at those coordinates: %d %d", x, y);
  1896.     return TCL_ERROR;
  1897.     }
  1898.     if (filePtr != NULL) {
  1899.     WishChangeSelection(aWindow, (ClientData) filePtr, TRUE, lineP,
  1900.         FALSE);
  1901.     } else {
  1902.     WishChangeSelection(aWindow, (ClientData) groupPtr, FALSE, FALSE,
  1903.         FALSE);
  1904.     }
  1905.  
  1906.     return TCL_OK;
  1907. }
  1908.  
  1909. void
  1910. WishCmdTableInit(cmdTablePtr, interpPtr, commands, clientData)
  1911.     Cmd_Table    *cmdTablePtr;
  1912.     Tcl_Interp    **interpPtr;
  1913.     CmdInfo    commands[];
  1914.     ClientData    clientData;
  1915. {
  1916.     CmdInfo    *cmd;
  1917.     int        i;
  1918.  
  1919.     *cmdTablePtr = Cmd_TableCreate();
  1920.     *interpPtr = Tcl_CreateInterp(); 
  1921.     for (cmd = commands; cmd->name != NULL; cmd++) {
  1922.     Tcl_CreateCommand(*interpPtr, cmd->name, cmd->proc, clientData,
  1923.         (void (*)()) NULL);
  1924.     }
  1925.     for (i = insertFirst; i <= insertLast; i++) {
  1926.     char    string[2];
  1927.  
  1928.     string[0] = i;
  1929.     string[1] = 0;
  1930.     Cmd_BindingCreate(*cmdTablePtr, string, "!@@");
  1931.     }
  1932.  
  1933.     return;
  1934. }
  1935.  
  1936.  
  1937. /*
  1938.  *----------------------------------------------------------------------
  1939.  *
  1940.  * WishAddGroupBinding --
  1941.  *
  1942.  *    Add a command binding to a file group.
  1943.  *
  1944.  * Results:
  1945.  *    None.
  1946.  *
  1947.  * Side effects:
  1948.  *    New command binding added to given group.
  1949.  *
  1950.  *----------------------------------------------------------------------
  1951.  */
  1952. void
  1953. WishAddGroupBinding(grpPtr, button, command)
  1954.     WishGroup        *grpPtr;
  1955.     int            button;            /* button binding */
  1956.     char        *command;
  1957. {
  1958.     WishGroupBinding    *bPtr;
  1959.  
  1960.     for (bPtr = grpPtr->groupBindings; bPtr != NULL; bPtr = bPtr->nextPtr) {
  1961.     if (bPtr->button == button) {
  1962.         /* substitute command and return */
  1963.         if (bPtr->command != NULL) {
  1964.         free(bPtr->command);
  1965.         }
  1966.         bPtr->command = Util_Strcpy(NULL, command);
  1967.         return;
  1968.     }
  1969.     }
  1970.     /* Not there already */
  1971.     bPtr = (WishGroupBinding *) malloc(sizeof (WishGroupBinding));
  1972.     bPtr->button = button;
  1973.     bPtr->command = Util_Strcpy(NULL, command);
  1974.     bPtr->nextPtr = grpPtr->groupBindings;
  1975.     grpPtr->groupBindings = bPtr;
  1976.  
  1977.     return;
  1978. }
  1979.  
  1980. void
  1981. WishDeleteGroupBindings(grpPtr)
  1982.     WishGroup    *grpPtr;
  1983. {
  1984.     WishGroupBinding    *bPtr, *nPtr;
  1985.  
  1986.     for (bPtr = grpPtr->groupBindings; bPtr != NULL; ) {
  1987.     nPtr = bPtr->nextPtr;
  1988.     free(bPtr->command);
  1989.     free(bPtr);
  1990.     bPtr = nPtr;
  1991.     }
  1992.     grpPtr->groupBindings = NULL;
  1993.  
  1994.     return;
  1995. }
  1996.  
  1997. void
  1998. WishDeleteGroupBinding(grpPtr, button)
  1999.     WishGroup    *grpPtr;
  2000.     int        button;
  2001. {
  2002.     WishGroupBinding    *bPtr, *nPtr;
  2003.  
  2004.     if (grpPtr->groupBindings == NULL) {
  2005.     return;
  2006.     }
  2007.     if (grpPtr->groupBindings->button == button) {
  2008.     bPtr = grpPtr->groupBindings;
  2009.     grpPtr->groupBindings = grpPtr->groupBindings->nextPtr;
  2010.     free(bPtr->command);
  2011.     free(bPtr);
  2012.  
  2013.     return;
  2014.     }
  2015.     for (bPtr = grpPtr->groupBindings; bPtr->nextPtr != NULL;
  2016.         bPtr = bPtr->nextPtr ) {
  2017.     nPtr = bPtr->nextPtr;
  2018.     if (nPtr->button == button) {
  2019.         bPtr->nextPtr = nPtr->nextPtr;
  2020.         free(nPtr->command);
  2021.         free(nPtr);
  2022.         return;
  2023.     }
  2024.     }
  2025.  
  2026.     return;
  2027. }
  2028.  
  2029.  
  2030.  
  2031. char *
  2032. WishGetGroupBinding(grpPtr, button)
  2033.     WishGroup    *grpPtr;
  2034.     int        button;
  2035. {
  2036.     WishGroupBinding    *bPtr;
  2037.  
  2038.     for (bPtr = grpPtr->groupBindings; bPtr != NULL; bPtr = bPtr->nextPtr) {
  2039.     if (bPtr->button == button) {
  2040.         break;
  2041.     }
  2042.     }
  2043.     if (bPtr == NULL) {
  2044.     return NULL;
  2045.     }
  2046.     return bPtr->command;
  2047. }
  2048.  
  2049.  
  2050.  
  2051. /*
  2052.  *----------------------------------------------------------------------
  2053.  *
  2054.  * WishDoCmd --
  2055.  *
  2056.  *    Execute a given Tcl command in a given window, and display
  2057.  *    error information if the command doesn't complete successfully.
  2058.  *
  2059.  * Results:
  2060.  *    Returns the result code from the command: TCL_OK, etc.
  2061.  *
  2062.  * Side effects:
  2063.  *    Can be almost arbitrary, depending on the command.
  2064.  *
  2065.  *----------------------------------------------------------------------
  2066.  */
  2067. int
  2068. WishDoCmd(aWindow, command)
  2069.     WishWindow    *aWindow;
  2070.     char    *command;
  2071. {
  2072.     int        result;
  2073.  
  2074.     result = Tcl_Eval(aWindow->interp, command, 0, (char **) 0);
  2075.     if (result == TCL_OK) {
  2076. #ifdef NOTDEF
  2077.     if (*aWindow->interp->result != 0) {
  2078. /* this won't work with close command, interpreter and window structure gone! */
  2079.         /*
  2080.          * output message - should call routine that uses 1-line window
  2081.          * if possible.
  2082.          */
  2083.     }
  2084. #endif NOTDEF
  2085.     return result;
  2086.     }
  2087.  
  2088.     WishPrintTclError(aWindow);
  2089.  
  2090.     return result;
  2091. }
  2092.  
  2093.  
  2094. /*
  2095.  * Local procedure used to turn empty or "-" strings into NULLs.
  2096.  */
  2097. static char *
  2098. GetString(string)
  2099.     char *string;
  2100. {
  2101.     if ((string[0] == 0) || ((string[0] == '-') && (string[1] == 0))) {
  2102.     return NULL;
  2103.     }
  2104.     return string;
  2105. }
  2106.  
  2107. int
  2108. WishWhichButton(token)
  2109.     char    *token;
  2110. {
  2111.  
  2112.     if (strcmp(token, "Left") == 0 ||
  2113.         strcmp(token, "left") == 0) {
  2114.     return WISH_LEFT_BUTTON;
  2115.     }
  2116.     if (strcmp(token, "Middle") == 0 ||
  2117.         strcmp(token, "middle") == 0) {
  2118.     return WISH_MIDDLE_BUTTON;
  2119.     }
  2120.     if (strcmp(token, "Right") == 0 ||
  2121.         strcmp(token, "right") == 0) {
  2122.     return WISH_RIGHT_BUTTON;
  2123.     }
  2124.     if (strcmp(token, "Meta") == 0 ||
  2125.         strcmp(token, "meta") == 0) {
  2126.     return WISH_META_BUTTON;
  2127.     }
  2128.     if (strcmp(token, "Shift") == 0 ||
  2129.         strcmp(token, "shift") == 0) {
  2130.     return WISH_SHIFT_BUTTON;
  2131.     }
  2132.     return 0;
  2133. }
  2134. @
  2135.  
  2136.  
  2137. 1.4
  2138. log
  2139. @Temporary checkin
  2140. @
  2141. text
  2142. @d18 1
  2143. a18 1
  2144. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishCmd.c,v 1.3 88/11/03 19:44:00 mlgray Exp Locker: mlgray $ SPRITE (Berkeley)";
  2145. d679 4
  2146. d691 1
  2147. d698 1
  2148. a698 1
  2149.         aWindow->interp->result, NULL, TRUE, "Continue", (char *) NULL);
  2150. @
  2151.  
  2152.  
  2153. 1.3
  2154. log
  2155. @Fixed many bugs - notifiers no longer trash the display.
  2156. @
  2157. text
  2158. @d18 1
  2159. a18 1
  2160. static char rcsid[] = "$Header: /a/newcmds/wish/RCS/wishCmd.c,v 1.2 88/11/02 14:49:18 mlgray Exp Locker: mlgray $ SPRITE (Berkeley)";
  2161. @
  2162.  
  2163.  
  2164. 1.2
  2165. log
  2166. @fsflat changed to wish
  2167. @
  2168. text
  2169. @d18 1
  2170. a18 1
  2171. static char rcsid[] = "$Header: wishCmd.c,v 1.1 88/10/03 12:45:42 mlgray Exp $ SPRITE (Berkeley)";
  2172. d147 1
  2173. a147 1
  2174.  *    Change the method of sorting directory entries.
  2175. d172 3
  2176. d197 1
  2177. a197 1
  2178.         aWindow->displayInstructions |= FSFLAT_SIZE_FIELD;
  2179. d205 1
  2180. a205 1
  2181.         aWindow->displayInstructions |= FSFLAT_ATIME_FIELD;
  2182. d219 1
  2183. a219 1
  2184.         aWindow->displayInstructions |= FSFLAT_DTIME_FIELD;
  2185. d230 1
  2186. a230 1
  2187.         aWindow->displayInstructions |= FSFLAT_MTIME_FIELD;
  2188. d240 3
  2189. d247 1
  2190. a247 1
  2191.     aWindow->displayInstructions |= FSFLAT_SIZE_FIELD;
  2192. d255 1
  2193. a255 1
  2194.     aWindow->displayInstructions |= FSFLAT_ATIME_FIELD;
  2195. d263 1
  2196. a263 1
  2197.     aWindow->displayInstructions |= FSFLAT_MTIME_FIELD;
  2198. d271 1
  2199. a271 1
  2200.     aWindow->displayInstructions |= FSFLAT_DTIME_FIELD;
  2201. d278 3
  2202. d373 2
  2203. a374 1
  2204.         "/sprite2/users/oustser/mx10/mx");
  2205. d377 1
  2206. d388 1
  2207. d391 1
  2208. d394 2
  2209. a395 2
  2210.     if (aWindow->sortingInstructions & FSFLAT_ALPHA_SORT) {
  2211.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  2212. d401 2
  2213. a402 2
  2214.     if (aWindow->sortingInstructions & FSFLAT_ATIME_SORT) {
  2215.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  2216. d408 2
  2217. a409 2
  2218.     if (aWindow->sortingInstructions & FSFLAT_MTIME_SORT) {
  2219.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  2220. d415 2
  2221. a416 2
  2222.     if (aWindow->sortingInstructions & FSFLAT_DTIME_SORT) {
  2223.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  2224. d422 2
  2225. a423 2
  2226.     if (aWindow->sortingInstructions & FSFLAT_SIZE_SORT) {
  2227.     if (aWindow->sortingInstructions & FSFLAT_REVERSE_SORT) {
  2228. d429 1
  2229. a429 1
  2230.     if (aWindow->displayInstructions & FSFLAT_NAME_FIELD) {
  2231. d432 1
  2232. a432 1
  2233.     if (aWindow->displayInstructions & FSFLAT_ATIME_FIELD) {
  2234. d435 1
  2235. a435 1
  2236.     if (aWindow->displayInstructions & FSFLAT_MTIME_FIELD) {
  2237. d438 1
  2238. a438 1
  2239.     if (aWindow->displayInstructions & FSFLAT_DTIME_FIELD) {
  2240. d441 1
  2241. a441 1
  2242.     if (aWindow->displayInstructions & FSFLAT_SIZE_FIELD) {
  2243. d691 1
  2244. d694 1
  2245. d869 2
  2246. d872 1
  2247. d877 1
  2248. d880 1
  2249. a880 1
  2250.         aWindow->sortingInstructions = FSFLAT_ALPHA_SORT;
  2251. d883 1
  2252. a883 1
  2253.         aWindow->sortingInstructions = FSFLAT_ATIME_SORT;
  2254. d886 1
  2255. a886 1
  2256.         aWindow->sortingInstructions = FSFLAT_MTIME_SORT;
  2257. d889 1
  2258. a889 1
  2259.         aWindow->sortingInstructions = FSFLAT_DTIME_SORT;
  2260. d892 1
  2261. a892 1
  2262.         aWindow->sortingInstructions = FSFLAT_SIZE_SORT;
  2263. d897 1
  2264. d900 1
  2265. d903 1
  2266. d907 1
  2267. d909 1
  2268. a909 1
  2269.         aWindow->sortingInstructions |= FSFLAT_REVERSE_SORT;
  2270. d970 1
  2271. a970 1
  2272.         aWindow->sortingInstructions |= FSFLAT_REVERSE_SORT;
  2273. d974 1
  2274. a974 1
  2275.         aWindow->sortingInstructions |= FSFLAT_ALPHA_SORT;
  2276. d981 1
  2277. a981 1
  2278.         aWindow->sortingInstructions |= FSFLAT_ATIME_SORT;
  2279. d994 1
  2280. a994 1
  2281.         aWindow->sortingInstructions |= FSFLAT_MTIME_SORT;
  2282. d1008 1
  2283. a1008 1
  2284.         aWindow->sortingInstructions |= FSFLAT_DTIME_SORT;
  2285. d1012 1
  2286. a1012 1
  2287.         aWindow->sortingInstructions |= FSFLAT_SIZE_SORT;
  2288. d1017 1
  2289. a1017 1
  2290.     getAttrsP = FSFLAT_ATTR_NECESSARY_P;
  2291. d1038 1
  2292. d1042 1
  2293. d1151 2
  2294. a1152 2
  2295.     length = argc;    /* spaces between command words + insert word */
  2296.     for (i = 0; i < argc; i++) {
  2297. d1158 1
  2298. a1158 1
  2299.     for (i = 0; i < argc; i++) {
  2300. d2064 1
  2301. a2064 1
  2302.     return FSFLAT_LEFT_BUTTON;
  2303. d2068 1
  2304. a2068 1
  2305.     return FSFLAT_MIDDLE_BUTTON;
  2306. d2072 1
  2307. a2072 1
  2308.     return FSFLAT_RIGHT_BUTTON;
  2309. d2076 1
  2310. a2076 1
  2311.     return FSFLAT_META_BUTTON;
  2312. d2080 1
  2313. a2080 1
  2314.     return FSFLAT_SHIFT_BUTTON;
  2315. @
  2316.  
  2317.  
  2318. 1.1
  2319. log
  2320. @Initial revision
  2321. @
  2322. text
  2323. @d2 1
  2324. a2 1
  2325.  * fsflatCmd.c --
  2326. d4 1
  2327. a4 1
  2328.  *    Commands for fsflat.
  2329. d18 1
  2330. a18 1
  2331. static char rcsid[] = "$Header: fsflatCmd.c,v 1.8 88/06/10 13:13:49 mlgray Exp $ SPRITE (Berkeley)";
  2332. d29 1
  2333. a29 1
  2334. #include "fsflatInt.h"
  2335. d43 1
  2336. a43 1
  2337.  * FsflatBindCmd --
  2338. d63 2
  2339. a64 2
  2340. FsflatBindCmd(aWindow, interp, argc, argv)
  2341.     FsflatWindow    *aWindow;
  2342. d86 1
  2343. a86 1
  2344.  * FsflatChangeDirCmd --
  2345. d103 2
  2346. a104 2
  2347. FsflatChangeDirCmd(aWindow, interp, argc, argv)
  2348.     FsflatWindow    *aWindow;
  2349. d135 1
  2350. a135 1
  2351.     FsflatChangeDir(aWindow, newDir);    /* does everything */
  2352. d145 1
  2353. a145 1
  2354.  * FsflatChangeFieldsCmd --
  2355. d163 2
  2356. a164 2
  2357. FsflatChangeFieldsCmd(aWindow, interp, argc, argv)
  2358.     FsflatWindow    *aWindow;
  2359. d237 1
  2360. a237 1
  2361.     which = Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2362. d245 1
  2363. a245 1
  2364.     which = Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2365. d253 1
  2366. a253 1
  2367.     which = Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2368. d261 1
  2369. a261 1
  2370.     which = Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2371. d277 1
  2372. a277 1
  2373.     FsflatSetPositions(aWindow);
  2374. d288 1
  2375. a288 1
  2376.  * FsflatChangeGroupsCmd --
  2377. d306 2
  2378. a307 2
  2379. FsflatChangeGroupsCmd(aWindow, interp, argc, argv)
  2380.     FsflatWindow    *aWindow;
  2381. d318 1
  2382. a318 1
  2383.     FsflatGroup    *grpPtr;
  2384. d330 1
  2385. a330 1
  2386.     sprintf(buffer, "%s%d.%d", "/tmp/tmpFsflat", pid, count);
  2387. d363 1
  2388. a363 1
  2389.     sprintf(fsflatErrorMsg, "Exec of %s returned.",
  2390. d365 2
  2391. a366 2
  2392.     Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2393.         fsflatErrorMsg, NULL, TRUE, "Skip command", (char *) NULL);
  2394. d374 1
  2395. a374 1
  2396.     sprintf(fsflatErrorMsg, "%s %s %s",
  2397. d377 2
  2398. a378 2
  2399.     Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2400.         fsflatErrorMsg, NULL, TRUE, "Skip command", (char *) NULL);
  2401. d433 1
  2402. a433 1
  2403.     FsflatGarbageCollect(aWindow);
  2404. d438 1
  2405. a438 1
  2406.     if (FsflatGatherNames(aWindow, buffer) != TCL_OK) {
  2407. d446 2
  2408. a447 2
  2409.     FsflatSetPositions(aWindow);
  2410.     /* FsflatRedraw will be called from event caused in FsflatSetPositions() */
  2411. d460 1
  2412. a460 1
  2413.  * FsflatChangeGroupCmd --
  2414. d476 2
  2415. a477 2
  2416. FsflatChangeGroupCmd(aWindow, interp, argc, argv)
  2417.     FsflatWindow    *aWindow;
  2418. d482 3
  2419. a484 3
  2420.     FsflatGroup    *grpPtr;
  2421.     FsflatGroup    *newGrpPtr;
  2422.     FsflatGroup    *bPtr;
  2423. d530 1
  2424. a530 1
  2425.     newGrpPtr = (FsflatGroup *) malloc(sizeof (FsflatGroup));
  2426. d540 1
  2427. a540 1
  2428.     FsflatGarbageGroup(aWindow, grpPtr);
  2429. d552 1
  2430. a552 1
  2431.     FsflatSetPositions(aWindow);
  2432. d576 1
  2433. a576 1
  2434.     FsflatWindow    *aWindow;
  2435. d579 1
  2436. a579 1
  2437.     FsflatGroup        *newGrpPtr;
  2438. d616 1
  2439. a616 1
  2440.     if (FsflatDoTclSelect(interp, newGrpPtr->rule, "x", &num) != TCL_OK) {
  2441. d636 1
  2442. a636 1
  2443.     if (FsflatGatherSingleGroup(aWindow, newGrpPtr) != TCL_OK) {
  2444. d649 1
  2445. a649 1
  2446.  * FsflatPrintTclError --
  2447. d662 2
  2448. a663 2
  2449. FsflatPrintTclError(aWindow)
  2450.     FsflatWindow    *aWindow;
  2451. d678 1
  2452. a678 1
  2453.     Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2454. d690 1
  2455. a690 1
  2456.  * FsflatDefineGroupCmd --
  2457. d708 2
  2458. a709 2
  2459. FsflatDefineGroupCmd(aWindow, interp, argc, argv)
  2460.     FsflatWindow    *aWindow;
  2461. d714 2
  2462. a715 2
  2463.     FsflatGroup    *grpPtr;
  2464.     FsflatGroup    *newGrpPtr;
  2465. d738 1
  2466. a738 1
  2467.     newGrpPtr = (FsflatGroup *) malloc(sizeof (FsflatGroup));
  2468. d743 2
  2469. a744 2
  2470.     FsflatPrintTclError(aWindow);
  2471.     FsflatDoCmd(aWindow, "close");
  2472. d769 1
  2473. a769 1
  2474.     FsflatSetPositions(aWindow);
  2475. d778 1
  2476. a778 1
  2477.  * FsflatSelectionCmd --
  2478. d796 2
  2479. a797 2
  2480. FsflatSelectionCmd(aWindow, interp, argc, argv)
  2481.     FsflatWindow    *aWindow;
  2482. d813 1
  2483. a813 1
  2484.  * FsflatSortFilesCmd --
  2485. d833 2
  2486. a834 2
  2487. FsflatSortFilesCmd(aWindow, interp, argc, argv)
  2488.     FsflatWindow    *aWindow;
  2489. d855 1
  2490. a855 1
  2491.     which = Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2492. d876 1
  2493. a876 1
  2494.         sprintf(fsflatErrorMsg, "%s %s", "Something is wrong.",
  2495. d878 2
  2496. a879 2
  2497.         Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2498.             fsflatErrorMsg, "Skip command", (char *) NULL);
  2499. d882 1
  2500. a882 1
  2501.     which = Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1, 0,
  2502. d888 1
  2503. a888 1
  2504.     FsflatSetSort(aWindow, NULL, NULL);
  2505. d890 1
  2506. a890 1
  2507.     FsflatSetSort(aWindow, argv[1], NULL);
  2508. d892 1
  2509. a892 1
  2510.     FsflatSetSort(aWindow, argv[1], argv[2]);
  2511. d905 1
  2512. a905 1
  2513.     FsflatSetPositions(aWindow);
  2514. d915 1
  2515. a915 1
  2516.  * FsflatSetSort --
  2517. d932 2
  2518. a933 2
  2519. FsflatSetSort(aWindow, sortMethod, reverse)
  2520.     FsflatWindow    *aWindow;
  2521. d938 2
  2522. a939 2
  2523.     FsflatFile    *tmpPtr;
  2524.     FsflatGroup    *grpPtr;
  2525. d941 1
  2526. a941 1
  2527.     FsflatFile    **fileArray;
  2528. d998 2
  2529. a999 2
  2530.     /* need comparison function that takes ptrs to FsflatFiles */
  2531.     FsflatGetCompareProc(aWindow, &compareProc, TRUE);
  2532. d1013 1
  2533. a1013 1
  2534.             sprintf(fsflatErrorMsg, "%s %s.",
  2535. d1015 2
  2536. a1016 2
  2537.             Sx_Notify(fsflatDisplay, aWindow->surroundingWindow, -1, -1,
  2538.                 0, fsflatErrorMsg, NULL, TRUE, "Continue",
  2539. d1023 2
  2540. a1024 2
  2541.     fileArray = (FsflatFile **) malloc(arraySize *
  2542.         sizeof (FsflatFile *));
  2543. d1029 1
  2544. a1029 1
  2545.     qsort(fileArray, arraySize, sizeof (FsflatFile *), compareProc);
  2546. d1046 1
  2547. a1046 1
  2548.  * FsflatCloseCmd --
  2549. d1065 2
  2550. a1066 2
  2551. FsflatCloseCmd(aWindow, interp, argc, argv)
  2552.     register    FsflatWindow    *aWindow;
  2553. d1075 2
  2554. a1076 2
  2555.     XDeleteContext(fsflatDisplay, aWindow->surroundingWindow,
  2556.         fsflatWindowContext);
  2557. d1078 2
  2558. a1079 2
  2559.     FsflatGarbageCollect(aWindow);
  2560.     XDestroyWindow(fsflatDisplay, aWindow->surroundingWindow);
  2561. d1082 2
  2562. a1083 2
  2563.     fsflatWindowCount--;
  2564.     if (fsflatWindowCount <= 0) {
  2565. d1093 1
  2566. a1093 1
  2567.  * FsflatExecCmd --
  2568. d1115 2
  2569. a1116 2
  2570. FsflatExecCmd(aWindow, interp, argc, argv)
  2571.     FsflatWindow    *aWindow;
  2572. d1137 1
  2573. a1137 1
  2574.     result = Tx_Command(fsflatDisplay, aWindow->txOutsideWindow, command);
  2575. d1147 1
  2576. a1147 1
  2577.  * FsflatGroupBindCmd --
  2578. d1164 2
  2579. a1165 2
  2580. FsflatGroupBindCmd(aWindow, interp, argc, argv)
  2581.     FsflatWindow    *aWindow;
  2582. d1170 1
  2583. a1170 1
  2584.     FsflatGroup    *grpPtr;
  2585. d1198 1
  2586. a1198 1
  2587.     test = FsflatWhichButton(buttonArgv[i]);
  2588. d1209 1
  2589. a1209 1
  2590.     FsflatAddGroupBinding(grpPtr, button, argv[3]);
  2591. d1218 1
  2592. a1218 1
  2593.  * FsflatMenuCmd --
  2594. d1238 2
  2595. a1239 2
  2596. FsflatMenuCmd(aWindow, interp, argc, argv)
  2597.     register    FsflatWindow    *aWindow;
  2598. d1269 1
  2599. a1269 1
  2600.     window = Sx_MenuGetWindow(fsflatDisplay, aWindow->menuBar, argv[2]);
  2601. d1273 1
  2602. a1273 1
  2603.     numEntries = Sx_MenuGetInfo(fsflatDisplay, window, entries, &fontPtr,
  2604. d1282 1
  2605. a1282 1
  2606.         Util_StringToColor(fsflatDisplay, argv[6]);
  2607. d1284 1
  2608. a1284 1
  2609.     entries[numEntries].proc = FsflatMenuProc;
  2610. d1288 1
  2611. a1288 1
  2612.     Sx_MenuCreate(fsflatDisplay, aWindow->menuBar, argv[2], numEntries+1,
  2613. d1313 1
  2614. a1313 1
  2615.             Util_StringToColor(fsflatDisplay, argv[arg+3]);
  2616. d1315 1
  2617. a1315 1
  2618.         entries[i].proc = FsflatMenuProc;
  2619. d1318 1
  2620. a1318 1
  2621.     Sx_MenuCreate(fsflatDisplay, aWindow->menuBar, argv[2], numEntries,
  2622. d1332 1
  2623. a1332 1
  2624.     window = Sx_MenuGetWindow(fsflatDisplay, aWindow->menuBar, argv[2]);
  2625. d1336 1
  2626. a1336 1
  2627.     count = Sx_MenuGetInfo(fsflatDisplay, window, entries,
  2628. d1341 1
  2629. a1341 1
  2630.     XDestroyWindow(fsflatDisplay, window);
  2631. d1407 1
  2632. a1407 1
  2633.     window = Sx_MenuGetWindow(fsflatDisplay, aWindow->menuBar, argv[2]);
  2634. d1412 1
  2635. a1412 1
  2636.     if ((index < 0) || (index >= Sx_MenuGetInfo(fsflatDisplay, window,
  2637. d1424 2
  2638. a1425 2
  2639.     entry.background = Util_StringToColor(fsflatDisplay, argv[7]);
  2640.     entry.proc = FsflatMenuProc;
  2641. d1427 1
  2642. a1427 1
  2643.     Sx_MenuReplaceEntry(fsflatDisplay, window, index, &entry);
  2644. d1445 1
  2645. a1445 1
  2646.  * FsflatOpenCmd --
  2647. d1447 1
  2648. a1447 1
  2649.  *    Create another fsflat window.
  2650. d1465 2
  2651. a1466 2
  2652. FsflatOpenCmd(aWindow, interp, argc, argv)
  2653.     FsflatWindow    *aWindow;
  2654. d1477 1
  2655. a1477 1
  2656.     if (FsflatCreate(aWindow, argv[1]) == NULL) {
  2657. d1480 1
  2658. a1480 1
  2659.     } else if (FsflatCreate(aWindow, NULL) == NULL) {
  2660. d1491 1
  2661. a1491 1
  2662.  * FsflatPatternCompareCmd --
  2663. d1509 2
  2664. a1510 2
  2665. FsflatPatternCompareCmd(aWindow, interp, argc, argv)
  2666.     register    FsflatWindow    *aWindow;
  2667. d1531 1
  2668. a1531 1
  2669.  * FsflatQuitCmd --
  2670. d1548 2
  2671. a1549 2
  2672. FsflatQuitCmd(aWindow, interp, argc, argv)
  2673.     register    FsflatWindow    *aWindow;
  2674. d1566 1
  2675. a1566 1
  2676.  * FsflatRestartCmd --
  2677. d1584 2
  2678. a1585 2
  2679. FsflatRestartCmd(aWindow, interp, argc, argv)
  2680.     FsflatWindow    *aWindow;
  2681. d1593 1
  2682. a1593 1
  2683.     FsflatGarbageCollect(aWindow);
  2684. d1595 1
  2685. a1595 1
  2686.     if (FsflatGatherNames(aWindow) != TCL_OK) {
  2687. d1600 2
  2688. a1601 2
  2689.     FsflatSetPositions(aWindow);
  2690.     /* FsflatRedraw will be called from event caused in FsflatSetPositions() */
  2691. d1611 1
  2692. a1611 1
  2693.  * FsflatRedrawCmd --
  2694. d1628 2
  2695. a1629 2
  2696. FsflatRedrawCmd(aWindow, interp, argc, argv)
  2697.     register    FsflatWindow    *aWindow;
  2698. d1635 1
  2699. a1635 1
  2700.     FsflatRedraw(aWindow);
  2701. d1644 1
  2702. a1644 1
  2703.  * FsflatResizeCmd --
  2704. d1660 2
  2705. a1661 2
  2706. FsflatResizeCmd(aWindow, interp, argc, argv)
  2707.     register    FsflatWindow    *aWindow;
  2708. d1684 1
  2709. a1684 1
  2710.     FsflatSetWindowAndRowInfo(aWindow, height, width);
  2711. d1691 1
  2712. a1691 1
  2713.     FsflatSetPositions(aWindow);
  2714. d1693 1
  2715. a1693 1
  2716.      * FsflatRedraw will be called from event caused in FsflatSetPostions().
  2717. d1704 1
  2718. a1704 1
  2719.  * FsflatToggleSelEntryCmd --
  2720. d1721 2
  2721. a1722 2
  2722. FsflatToggleSelEntryCmd(aWindow, interp, argc, argv)
  2723.     register    FsflatWindow    *aWindow;
  2724. d1728 2
  2725. a1729 2
  2726.     FsflatFile    *filePtr;
  2727.     FsflatGroup    *groupPtr = NULL;
  2728. d1752 1
  2729. a1752 1
  2730.     filePtr = FsflatMapCoordsToFile(aWindow, x, y);
  2731. d1759 1
  2732. a1759 1
  2733.     FsflatChangeSelection(aWindow, (ClientData) filePtr, TRUE, lineP, TRUE);
  2734. d1761 1
  2735. a1761 1
  2736.     FsflatChangeSelection(aWindow, (ClientData) groupPtr, FALSE, FALSE,
  2737. d1771 1
  2738. a1771 1
  2739.  * FsflatToggleSelectionCmd --
  2740. d1787 2
  2741. a1788 2
  2742. FsflatToggleSelectionCmd(aWindow, interp, argc, argv)
  2743.     register    FsflatWindow    *aWindow;
  2744. d1793 2
  2745. a1794 2
  2746.     FsflatFile    *filePtr = NULL;
  2747.     FsflatGroup    *groupPtr = NULL;        /* not used yet */
  2748. d1817 1
  2749. a1817 1
  2750.     filePtr = FsflatMapCoordsToFile(aWindow, x, y);
  2751. d1824 1
  2752. a1824 1
  2753.     FsflatChangeSelection(aWindow, (ClientData) filePtr, TRUE, lineP,
  2754. d1827 1
  2755. a1827 1
  2756.     FsflatChangeSelection(aWindow, (ClientData) groupPtr, FALSE, FALSE,
  2757. d1835 1
  2758. a1835 1
  2759. FsflatCmdTableInit(cmdTablePtr, interpPtr, commands, clientData)
  2760. d1865 1
  2761. a1865 1
  2762.  * FsflatAddGroupBinding --
  2763. d1878 2
  2764. a1879 2
  2765. FsflatAddGroupBinding(grpPtr, button, command)
  2766.     FsflatGroup        *grpPtr;
  2767. d1883 1
  2768. a1883 1
  2769.     FsflatGroupBinding    *bPtr;
  2770. d1896 1
  2771. a1896 1
  2772.     bPtr = (FsflatGroupBinding *) malloc(sizeof (FsflatGroupBinding));
  2773. d1906 2
  2774. a1907 2
  2775. FsflatDeleteGroupBindings(grpPtr)
  2776.     FsflatGroup    *grpPtr;
  2777. d1909 1
  2778. a1909 1
  2779.     FsflatGroupBinding    *bPtr, *nPtr;
  2780. d1923 2
  2781. a1924 2
  2782. FsflatDeleteGroupBinding(grpPtr, button)
  2783.     FsflatGroup    *grpPtr;
  2784. d1927 1
  2785. a1927 1
  2786.     FsflatGroupBinding    *bPtr, *nPtr;
  2787. d1957 2
  2788. a1958 2
  2789. FsflatGetGroupBinding(grpPtr, button)
  2790.     FsflatGroup    *grpPtr;
  2791. d1961 1
  2792. a1961 1
  2793.     FsflatGroupBinding    *bPtr;
  2794. d1979 1
  2795. a1979 1
  2796.  * FsflatDoCmd --
  2797. d1993 2
  2798. a1994 2
  2799. FsflatDoCmd(aWindow, command)
  2800.     FsflatWindow    *aWindow;
  2801. d2013 1
  2802. a2013 1
  2803.     FsflatPrintTclError(aWindow);
  2804. d2033 1
  2805. a2033 1
  2806. FsflatWhichButton(token)
  2807. @
  2808.